by

Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • Sep 04 09:47
    coveralls commented #199
  • Sep 04 09:45
    coveralls commented #208
  • Sep 04 09:44
    coveralls commented #204
  • Sep 04 09:43
    coveralls commented #203
  • Sep 04 09:42
    coveralls commented #202
  • Sep 04 09:41
    coveralls commented #210
  • Sep 04 09:40
    dependabot[bot] synchronize #199
  • Sep 04 09:40

    dependabot[bot] on npm_and_yarn

    Bump stringstream from 0.0.5 to… (compare)

  • Sep 04 09:39
    dependabot[bot] edited #199
  • Sep 04 09:39
    dependabot[bot] synchronize #208
  • Sep 04 09:39

    dependabot[bot] on npm_and_yarn

    Bump elliptic from 6.4.0 to 6.5… (compare)

  • Sep 04 09:39
    dependabot[bot] synchronize #204
  • Sep 04 09:39
    dependabot[bot] edited #208
  • Sep 04 09:39

    dependabot[bot] on npm_and_yarn

    Bump concat-stream from 1.4.10 … (compare)

  • Sep 04 09:39
    dependabot[bot] edited #204
  • Sep 04 09:39
    dependabot[bot] synchronize #203
  • Sep 04 09:39

    dependabot[bot] on npm_and_yarn

    Bump sshpk from 1.13.1 to 1.16.… (compare)

  • Sep 04 09:39
    dependabot[bot] synchronize #202
  • Sep 04 09:39
    dependabot[bot] edited #203
  • Sep 04 09:39

    dependabot[bot] on npm_and_yarn

    Bump eslint from 2.13.1 to 4.18… (compare)

Antti Niemenpää
@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 Niemenpää
@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 Niemenpää
@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 Niemenpää
@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 Niemenpää
@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 Niemenpää
@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 Niemenpää
@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 Niemenpää
@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 Niemenpää
@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 Niemenpää
@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.

Antti Niemenpää
@niant
Hey, I'd like to ask if flyd.chainshould work like this? or if this is a bug? because it seems like a bug:
const stream$ = flyd.stream(false);

flyd.chain(() => {
  console.log('this is called 3 times?');
  return flyd.stream('foobar');
}, filter(val => val, stream$));

stream$(true);
stream$(false);
stream$(false);
rektide
@rektide
Hi #flyd!! I just wanted to share this- the Apollo GraphQL people have a new "reactive variable" concept in their 3.0. You... you may recognize it!! apollographql/apollo-client#5799 (It's the flyd pattern!!)
Mike Panciera
@averagehat
any ideas about the differences between this library and hareactive?
I would like to contribute to hareactive a bit but I am not sure if flyd is the 'new and improved' or a separate and parallel project. https://github.com/funkia/hareactive
Mike Panciera
@averagehat
I'm also wondering if there are any performance outliers in either library which might keep them from seeing use in real-time applications (games or real-time graphics)
Einar Norðfjörð
@nordfjord
Hi there! As I understood paldepind, his more recent view on frp is encapsulated in hareactive, so I think hareactive is the new and improved flyd rather than the other way around
There’s a blog post here where you can read more about the thought process behind hareactive http://vindum.io/blog/behaviors-and-streams-why-both/
Mike Panciera
@averagehat
@nordfjord thanks
Patrik Johnson
@orbitbot
Just as a PoV, you might not necessarily need continuous state as described in the above blog post, depending on app features/complexity. It might be relevant to handle in different ways in any case, so reviewing options before commiting might be a decent idea