Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • Jul 06 18:06
    sourcevault closed #198
  • Jul 06 18:06
    sourcevault commented #198
  • Jul 05 21:50
    StreetStrider commented #198
  • Jul 05 19:28
    nordfjord commented #198
  • Jul 05 19:28
    nordfjord commented #198
  • Jul 05 16:19
    sourcevault opened #198
  • Apr 18 03:49
    Mapiac commented #22
  • Apr 18 03:49
    Mapiac commented #22
  • Apr 13 05:58
    Mapiac opened #197
  • Apr 01 17:41
    StreetStrider commented #196
  • Apr 01 17:32
    coveralls commented #196
  • Apr 01 17:30
    nordfjord commented #196
  • Apr 01 17:28
    nordfjord synchronize #196
  • Apr 01 17:28

    nordfjord on chain-test

    return promise instead of using… (compare)

  • Mar 29 18:37
    StreetStrider commented #196
  • Mar 29 16:53
    nordfjord commented #196
  • Mar 29 15:43
    StreetStrider commented #196
  • Mar 29 13:30
    nordfjord closed #118
  • Mar 29 13:24
    coveralls commented #196
  • Mar 29 13:24
    coveralls commented #196
Einar Norðfjörð
@nordfjord
I don’t think we can deprecate first and release later like you were talking about
because the helpers simply won’t work
flattenPromise excepts a Stream Promise a
which can’t exist in the current flyd implementation
Einar Norðfjörð
@nordfjord
It would be pretty easy to implement the monoid spec as well
Einar Norðfjörð
@nordfjord
since we already have a merge method
Strider
@StreetStrider
@paldepind hello. Why flyd does not prevent user from emitting second end value?
Strider
@StreetStrider
I would love to see this idea https://github.com/paldepind/flyd/issues/116#issuecomment-224702954 recieving approval.
Renato Marinho
@renatomarinho
This message was deleted
Antti
@niant
Hey, I've a weird problem with flyd.map when doing transformations inside a another flyd.map...
const log = message => val => {
  console.log(message, val);
  return val;
};

const stream$ = flyd.stream(false);

flyd.map(() => {
  stream$
    .map(log('this prints...'))
    .map(log('...but it never reaches here'));
}, flyd.stream(true));
Has anyone struggled with this kind of situation? (If I take the surrounding flyd.map() away it'll work correctly)
Einar Norðfjörð
@nordfjord
Yes, a few times. May I ask what your use case is for this? I found that in most places where I was creating new streams within another stream body it was a huge anti-pattern.
Einar Norðfjörð
@nordfjord

For instance if we further your example.

const log = a => b => (console.log(a), b);
const s1 = stream(true);
const s2 = stream(true);

s2.map(()=> s1.map(log('1')).map(log('2'))

s2(true)(true);

What is your expectation of logging here?

1
2
1
2
1
2

Or is it just

1
2

Imagine we add s1(true) to the end of the example

What is your logging expectation then?

Renato Marinho
@renatomarinho
This message was deleted
Antti
@niant

Well, this is hard one to explain. I just did a simplistic example to highlight the issues. Let me try:

One example of such use case is when for example we have react-like components working with state in flyd streams (setState updates via stream updates). There comes situations when there's stateful components inserted into DOM after the state stream has already been initiated. While initiating the component - it reads in stream state nicely, but if you try to map the stream into another stream (transform, drop repeats, pick only specific props...) it didn't work properly. paldepind/flyd#177 tries to highlight the issue in a different format, but the underlying issue seems the same.

The recent fix: paldepind/flyd#178 will fix this issue though.

Antti
@niant
And what comes to example code @nordfjord : Yes, that's a difficult question. I'd say the expected result is 1 2 and after adding s1(true) it becomes even trickier, but i'd throw in another suggestion 1 2 1 2 :)
Einar Norðfjörð
@nordfjord
I believe in order for it to be guaranteed 1 2 1 2 you will need to:
s2.map(()=> takeUntil(s1, s2).map(log('1')).map(log('2')));
no sorry, s2 receives three updates in the example, (an initial value, + 2 updates)
so it's always going to be 1 2 1 2 1 2
adding an s1(true) to the end would log the same, but in a semi random order (probably reversed)
Einar Norðfjörð
@nordfjord

I used to have a similar problem with a react-like framework called mithril, where I was calling:

s.map(m.redraw)

because a redraw was happening inside a stream body weird things could happen. I ended up replacing every .map(m.redraw) with
.map(()=> requestAnimationFrame(m.redraw)) to fix it

Antti
@niant
Yea, I mean there's a logic for both expected results in my head :) I'm not fully sure yet what is the correct way. I only got my understanding behind it, and nothing mathematical or even theoretical behind it.
Antti
@niant
Regarding requestAnimationFrame, that's a good tip though I'm not sure would that have solved our issue. Our framework of choice (Inferno) is doing that behind the scenes I assume.. I'll try to create another example describing our original issue maybe better...
Einar Norðfjörð
@nordfjord
If it's a react clone then the setState method is what's doing the redraw :)
so you could on your component do something like:
class MyComponent extends Component {
  redraw() {
    requestAnimationFrame(()=> this.setState(this.state));
  }
}
Antti
@niant
Yea, actually now that I think of it. The problem might've been mitigating from that kind of issue, if the operations are sync enough you might end up in situation where child component stream is handled inside a parent setState/redraw (thus inside a parents flyd.map/on).
If that made any sense (I just came back from a holiday so my brain is kind of adjusting here :D)
Einar Norðfjörð
@nordfjord
Made perfect sense, I was in exactly the same situation but with another framework
So we decided that redraws should be async by default, but still exposed a synchronous redraw for those situations where you really really need it
Antti
@niant
Yea. That sounds reasonable.. Hmm, now I just need to figure out the way it's currently working. From my understanding React did/is doing changes into setState() sync/async side of things too
Thanks for the insight! :)
Einar Norðfjörð
@nordfjord
My pleasure, to be clear though, I think it's slightly obnoxious if flyd requires you to use a framework with async redraws because of an issue with nested streams :). So I'm hoping #180 gets merged soon
Antti
@niant
Yea, I hope too. Also it seems there's been some talk in Inferno github pages on this sync/async setState and perhaps changes in a specific version. I need to check that out too.
Antti
@niant
I assume this was the part you were talking about with the semi random call order previously @nordfjord ? And it does seems a bit weird, that order is different outside and inside a flyd.map..
const log = message => val => {
  console.log(message, val);
  return val;
};

const stream$ = flyd.stream(true);

stream$.map(log('1')).map(log('2'));
console.log('3');

flyd.stream(true).map(() => {
  stream$.map(log('5')).map(log('6'));
  console.log('4');
});
Einar Norðfjörð
@nordfjord
It has to do with the guarantees flyd gives you. Atomic updates are guaranteed, but the execution order of streams is not.
const log = a => b => (console.log(a), b);

const stream$ = stream(true);
stream$.map(()=> {
  // flyd makes no guarantee that this chain will resolve instantly
  // we only guarantee atomic updates
  const s2 = stream$.map(log('1')).map(log('2'));
  console.log('3');
});
// It's only here that you can be sure that the map chain has run.
Antti
@niant
Yea..
Daniel Gray
@DanielFGray
is there a better way to someArray.forEach(x => myStream(x)) ? in rxjs i can flatMap arrays into the stream, but chain always expects a stream and i don't see anything that looks similar
Einar Norðfjörð
@nordfjord
you mean like a utility for
const fromArray = (list) => {
  const s = stream();
  // make sure the caller can process all values by
  // by putting the loop on the next tick
  setTimeout(()=> list.forEach(s));
  return s;
}
Daniel Gray
@DanielFGray
yeah, i guess? hm. how would i use that?
Einar Norðfjörð
@nordfjord

let's say you have a stream of type Stream<T[]> and you want to turn it into a Stream<T>

Then you could:

const myStream = stream([1,2,3]);
myStream.chain(fromArray).map(console.log);
// logs
// 1
// 2
// 3
here's a flems with an example
Daniel Gray
@DanielFGray
oh just .chain it, damn ok
thanks a lot!
Einar Norðfjörð
@nordfjord
My pleasure. Hope it helps
Dannel Albert
@nerdo
Hey all. I’m new to flyd and relatively new to reactive streams. I’m trying to make sense of the difference between map and pipe. It’s a little confusing. I’m very familiar with map in the functional sense but I don’t know when I would need or want to use pipe
also, what notation is being used for the function signatures in the api docs? i’m assuming its some sort of functional notation but it’s a little confusing and I think I missed the part in the docs that spells it out
Einar Norðfjörð
@nordfjord

Say you have a function that takes a type a and returns a type b. And say you have a stream that contains type a.

Then you can supply that function to the map method of the stream and receive a stream containing type b.

Pipe is a bit different.

Say you have a function that takes a stream of type a and returns a stream of type b. And a stream of type a.

Then you can supply that function to the streams pipe method to receive a stream of type b.

The type notation in the docs is Hindley milner.

Pipe is implemented as:

s.pipe = f => f(s)

And can be useful for things like flyd.scan.

Where the function is not a method on the stream

s.pipe(flyd.scan(reducer, initialValue))
Neville Franks
@getclibu_twitter

I'm using .map and need to execute an async function inside it to completion before it is called again. I've read the doc's and tried various things to no avail so far. For eaxmple this doesn't work:

const update = flyd.stream()

update.map( async patch => {
    await someAsyncFunction()   // don't call this again until it's promise resolves.
}).pipe( flyd.flattenPromise )

Hopefully someone more knowledgeable than me has a simple answer.