Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

introduce lazy stream as alternative to proxy #235

Open
samdesota opened this issue Jan 13, 2018 · 3 comments
Open

introduce lazy stream as alternative to proxy #235

samdesota opened this issue Jan 13, 2018 · 3 comments

Comments

@samdesota
Copy link

samdesota commented Jan 13, 2018

The current proxy design using .imitate is kinda a unusual api in world where almost all other stream creation operators are pure, and typescript can't automatically infer its type since it must be created before the result is available

What if instead, you used:

var first$ = xs.lazy(() => second$).map(x => x * 10).take(3);
var second$ = first$.map(x => x + 1).startWith(1).compose(delay(100));

Now, the type can be inferred with typescript and you don't need the extra lines for .imitate(). This works by creating a producer which stores the () => second$ function, then once .subscribe is called (after second$ has been assigned), () => second$ is called its result is observed

@samdesota samdesota changed the title introduce xs.lazy() as alternative to proxy introduce lazy stream as alternative to proxy Jan 13, 2018
@staltz
Copy link
Owner

staltz commented Jan 29, 2018

Nice idea, you could probably release this as a separate package. I think in xstream we will gradually take distance from the imitate API, which for Cycle.js purposes is starting to look less necessary.

@ftaiolivista
Copy link

ftaiolivista commented Oct 14, 2019

@mrapogee any news on your proposal? Would be great to have an implementation of It.

If I understand well it's a combination of of/map/flatten

import xs from 'xstream'

const first$ = xs
    .of(() => second$)
    .map(f => f())
    .flatten()
    .map(x => x * 10)

const second$ = first$.map(x => x + 1).startWith(1)

second$.addListener({
    next: i => console.log(i),
    error: err => console.error(err),
    complete: () => console.log('completed')
})

@samdesota
Copy link
Author

samdesota commented Oct 14, 2019

It's funny, I just started using xstream again this week. Ended up re-implementing lazy privately again via:

import xs from "xstream";

const lazy = getStream => {
  return xs.create({
    start(sink) {
      this.sub = getStream().subscribe(sink);
    },

    stop() {
      if (this.sub) {
        this.sub.unsubscribe();
        this.sub = null;
      }
    }
  });
};

Though given that xsteam is multicast, it might make more sense to do something like:

import xs from "xstream";

const empty = Symbol('empty')
const lazy = getStream => {
  return xs.create({
    stream: empty,

    start(sink) {
      if (this.stream === empty) {
        this.stream = getStream()
     }

      this.sub = this.stream.subscribe(sink);
    },

    stop() {
      if (this.sub) {
        this.sub.unsubscribe();
        this.sub = null;
      }
    }
  });
};

Maybe I'll get around to publishing it some time this week.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants