I'm trying to recreate RxMarbles for RxJS 5, but I'm having feedback problems when I change the collection's data (specifically the length of the data source).
I added console.log
s for debugging
Note for those who are familiar with RxMarbles, I renamed "Diagram" to "Timeline".
import { svg } from '@cycle/dom';
import isolate from '@cycle/isolate';
import { Observable } from 'rxjs';
import { apply, flip, map, max, merge, path, prop, sortBy, zip } from 'ramda';
import { Collection } from '../collection';
import { Marble } from './marble';
import { EndMarker } from './end-marker';
function sortMarbleDoms$(marbles$) {
const doms$ = Collection.pluck(marbles$, prop('DOM'));
const dataList$ = Collection.pluck(marbles$, prop('data'));
return Observable.combineLatest(doms$, dataList$, zip)
.map(sortBy(path([1, 'time'])))
.map(map(prop(0)));
}
function OriginalTimeline({ DOM, marbles: marblesState$, end: end$ }) {
const marblesProps$ = end$.map(({ time }) => ({
minTime: 0,
maxTime: time,
}));
const endMarkerProps$ = marblesState$.map(marbles => ({
minTime: marbles.map(prop('time')).reduce(max, 0),
maxTime: 100,
}));
const marblesSources = { DOM, props: marblesProps$ };
const endMarkerSources = {
DOM,
props: endMarkerProps$,
time: end$.pluck('time'),
};
const marbles$ = Collection.gather(
Marble, marblesSources, marblesState$
.do(a=>console.log('marblesState', a)), '_itemId');
const marbleDOMs$ = sortMarbleDoms$(marbles$);
const endMarker = EndMarker(endMarkerSources);
const vtree$ = Observable.combineLatest(marbleDOMs$, endMarker.DOM)
.map(([marbleDOMs, endMarkerDOM]) =>
svg({
attrs: { viewBox: '0 0 100 10' },
style: { width: 500, height: 50, overflow: 'visible' },
}, [
svg.line({
attrs: { x1: 0, x2: 100, y1: 5, y2: 5 },
style: { stroke: 'black', strokeWidth: 0.4 },
}),
endMarkerDOM,
...marbleDOMs,
])
);
const marbleData$ = Collection.pluck(marbles$, prop('data'))
.withLatestFrom(marblesState$, zip)
.map(map(apply(flip(merge))))
const data$ = Observable.combineLatest(marbleData$, endMarker.time)
.map(([marbles, endMarkerTime]) => ({
marbles,
end: { time: endMarkerTime },
}))
.debounceTime(1);
return { DOM: vtree$, data: data$.do(a=>console.log('tdata', a)) };
}
export function Timeline(sources) {
return isolate(OriginalTimeline)(sources);
}
The basic structure of the app is that all necessary data is fed into a global sink to a dummy driver that just takes the data and re-emits it as is (so in theory, all outputs should be new inputs).
Because of this, the problem might be in other parts of my code so I'm happy to post a codepen/plunkr of the code if it helps. This is indeed working sometimes, but not all the time.
Here's the console outputs (abridged)
store Object {route: "merge", inputs: undefined}
timeline.js:39 marblesState [Object, Object, Object, Object]
timeline.js:69 tdata Object {marbles: Array[3], end: Object}
sandbox.js:48 data [Object, Object]
app.js:26 store Object {route: "merge", inputs: Array[2]}
Notice the marblesState
has 4 objects, but the tdata
returns marbles with an array of 3 objects. For some reason, the Collection is only returning 3 items.
Any help is appreciated. Thanks!