UNPKG

30.6 kBMarkdownView Raw
1<!-- This README.md is automatically generated from source code and files in the /markdown directory. Please DO NOT send pull requests to directly modify this README. Instead, edit the JSDoc comments in source code or the md files in /markdown/. -->
2
3```text
4 _
5__ _____| |_ _ __ ___ __ _ _ __ ___
6\ \/ / __| __| '__/ _ \/ _` | '_ ` _ \
7 > <\__ \ |_| | | __/ (_| | | | | | |
8/_/\_\___/\__|_| \___|\__,_|_| |_| |_|
9```
10<h2 class="site-subtitle">An extremely intuitive, small, and fast<br />functional reactive stream library for JavaScript</h2>
11
12- Only 26 core operators and factories
13- Only ["hot"](https://medium.com/@benlesh/hot-vs-cold-observables-f8094ed53339#.mvzg5e7lf) streams
14- Written in TypeScript
15- Approximately 30 kB in size, when minified
16- On average, faster than RxJS 4, Kefir, Bacon.js, as fast as RxJS 5, and slower than most.js
17- Tailored for [Cycle.js](http://cycle.js.org), or applications with limited use of `subscribe`
18
19![](https://badge-size.herokuapp.com/staltz/xstream/master/dist/xstream.js.svg)
20![](https://badge-size.herokuapp.com/staltz/xstream/master/dist/xstream.min.js.svg?compression=gzip)
21[![ComVer](https://img.shields.io/badge/ComVer-compliant-brightgreen.svg)](https://github.com/staltz/comver)
22[![Gitter](https://img.shields.io/gitter/room/nwjs/nw.js.svg?maxAge=2592000)](https://gitter.im/staltz/xstream)
23
24# Example
25
26```js
27import xs from 'xstream'
28
29// Tick every second incremental numbers,
30// only pass even numbers, then map them to their square,
31// and stop after 5 seconds has passed
32
33var stream = xs.periodic(1000)
34 .filter(i => i % 2 === 0)
35 .map(i => i * i)
36 .endWhen(xs.periodic(5000).take(1))
37
38// So far, the stream is idle.
39// As soon as it gets its first listener, it starts executing.
40
41stream.addListener({
42 next: i => console.log(i),
43 error: err => console.error(err),
44 complete: () => console.log('completed'),
45})
46```
47
48# Installation
49
50```text
51npm install xstream
52```
53
54# Usage
55
56## ES2015 or TypeScript
57
58```js
59import xs from 'xstream'
60```
61
62## CommonJS
63
64```js
65var xs = require('xstream').default
66```
67
68# API
69
70## Factories
71- [`create`](#create)
72- [`createWithMemory`](#createWithMemory)
73- [`never`](#never)
74- [`empty`](#empty)
75- [`throw`](#throw)
76- [`from`](#from)
77- [`of`](#of)
78- [`fromArray`](#fromArray)
79- [`fromPromise`](#fromPromise)
80- [`fromObservable`](#fromObservable)
81- [`periodic`](#periodic)
82- [`merge`](#merge)
83- [`combine`](#combine)
84
85## Methods and Operators
86- [`addListener`](#addListener)
87- [`removeListener`](#removeListener)
88- [`subscribe`](#subscribe)
89- [`map`](#map)
90- [`mapTo`](#mapTo)
91- [`filter`](#filter)
92- [`take`](#take)
93- [`drop`](#drop)
94- [`last`](#last)
95- [`startWith`](#startWith)
96- [`endWhen`](#endWhen)
97- [`fold`](#fold)
98- [`replaceError`](#replaceError)
99- [`flatten`](#flatten)
100- [`compose`](#compose)
101- [`remember`](#remember)
102- [`debug`](#debug)
103- [`imitate`](#imitate)
104- [`shamefullySendNext`](#shamefullySendNext)
105- [`shamefullySendError`](#shamefullySendError)
106- [`shamefullySendComplete`](#shamefullySendComplete)
107- [`setDebugListener`](#setDebugListener)
108
109## Extra factories and operators
110
111To keep the core of xstream small and simple, less frequently-used methods are available under the `xstream/extra` directory, and must be imported separately. See [EXTRA_DOCS](https://github.com/staltz/xstream/blob/master/EXTRA_DOCS.md) for documentation.
112
113# Overview
114
115XStream has four fundamental types: [Stream](#stream), [Listener](#listener), [Producer](#producer), and [MemoryStream](#memorystream).
116
117## Stream
118
119A Stream is an **event emitter** with multiple Listeners. When an event happens on the
120Stream, it is broadcast to all its Listeners at the same time.
121
122Streams have methods attached to them called *operators*, such as `map`, `filter`, `fold`, `take`, etc. When called, an operator creates and returns another Stream. Once the first Stream broadcasts an event, the event will pass through the operator logic and the output Stream may perhaps broadcast its own event based on the source one.
123
124You can also trigger an event to happen on a Stream with the `shamefullySend*` methods. But you don't want to do that. Really, avoid doing that because it's not the reactive way and you'll be missing the point of this library. Ok?
125
126## Listener
127
128A Listener is an object with one to three functions attached to it: `next`, `error`, and `complete`. There is usually one function for each type of event a Stream may emit but only `next` is always required.
129
130- `next` events are the typical type, they deliver a value.
131- `error` events abort (stop) the execution of the Stream, and happen when something goes wrong in the Stream (or upstream somewhere in the chain of operators)
132- `complete` events signal the peaceful stop of the execution of the Stream.
133
134This is an example of a typical listener:
135
136```js
137var listener = {
138 next: (value) => {
139 console.log('The Stream gave me a value: ', value);
140 },
141 error: (err) => {
142 console.error('The Stream gave me an error: ', err);
143 },
144 complete: () => {
145 console.log('The Stream told me it is done.');
146 },
147}
148```
149
150And this is how you would attach that Listener to a Stream:
151
152<!-- skip-example -->
153```js
154stream.addListener(listener)
155```
156
157And when you think the Listener is done, you can remove it from the Stream:
158
159<!-- skip-example -->
160```js
161stream.removeListener(listener)
162```
163
164## Producer
165
166A Producer is like a machine that produces events to be broadcast on a Stream.
167
168Events from a Stream must come from somewhere, right? That's why we need Producers. They are objects with two functions attached: `start(listener)` and `stop()`. Once you call `start` with a `listener`, the Producer will start generating events and it will send those to the listener. When you call `stop()`, the Producer should quit doing its own thing.
169
170Streams are also Listeners (actually they are "InternalListeners", not Listeners, but that's a detail you can ignore), so you can theoretically give a Stream as the listener in `producer.start(streamAsListener)`. Then, essentially the Producer is now generating events that will be broadcast on the Stream. Nice, huh? Now a bunch of listeners can be attached to the Stream and they can all get those events originally coming from the Producer. That's why `xs.create(producer)` receives a Producer to be the heart of a new Stream. Check this out:
171
172```js
173var producer = {
174 start: function (listener) {
175 this.id = setInterval(() => listener.next('yo'), 1000)
176 },
177
178 stop: function () {
179 clearInterval(this.id)
180 },
181
182 id: 0,
183}
184
185// This fellow delivers a 'yo' next event every 1 second
186var stream = xs.create(producer)
187```
188
189But remember, a Producer has only one listener, but a Stream may have many listeners.
190
191You may wonder "when is `start` and `stop` called", and that's actually a fairly tricky topic, so let's get back to that soon. First let me tell you about MemoryStreams.
192
193## MemoryStream
194
195A MemoryStream is just like a Stream: it has operators, it can have listeners attached, you can shamefully send events to it, blabla. But it has one special property: it has *memory*. It remembers the most recent (but just one) `next` event that it sent to its listeners.
196
197Why is that useful? If a new Listener is added *after* that `next` event was sent, the MemoryStream will get its value stored in memory and will send it to the newly attached Listener.
198
199This is important so MemoryStreams can represent values or pieces of state which are relevant even after some time has passed. You don't want to lose those, you want to keep them and send them to Listeners that arrive late, after the event was originally created.
200
201## How a Stream starts and stops
202
203A Stream controls its Producer according to its number of Listeners, using reference counting with a synchronous `start` and a cancelable asynchronous `stop`. That's how a Stream starts and stops, basically. Usually this part of XStream is not so relevant to remember when building applications, but if you want to understand it for debugging or curiosity, it's explained in plain English below.
204
205When you create a Stream with `xs.create(producer)`, the `start()` function of the Producer is not yet called. The Stream is still "idle". It has the Producer, but the Producer was not turned on.
206
207Once the first Listener is added to the Stream, the number of Listeners attached suddenly changed from `0` to `1`. That's when the Stream calls `start`, because after all there is at least one Listener interested in this Stream.
208
209More Listeners may be added in the future, but they don't affect whether the Producer will continue working or stop. Just the first Listener dictates when the Stream starts.
210
211What matters for stopping the Producer is `stream.removeListener`. When the last Listener leaves (or in other words, when the number of Listeners suddenly changes from `1` to `0`), the Stream schedules `producer.stop()` **to happen on the next event loop**. That is, asynchronously. If, however, a new Listener is added (number goes from `0` to `1`) *before* that scheduled moment, the `producer.stop()` will be cancelled, and the Producer will continue generating events for its Stream normally.
212
213The reason the Producer is not suddenly (synchronously) stopped, is that it is often necessary to swap the single listener of a Stream, but still keep its ongoing execution. For instance:
214
215<!-- skip-example -->
216```js
217var listenerA = {/* ... */}
218var listenerB = {/* ... */}
219
220// number goes from 0 to 1, so the Stream's Producer starts
221stream.addListener(listenerA)
222
223// ...
224
225// number goes from 1 to 0, but then immediately goes back
226// to 1, because listenerB was added
227stream.removeListener(listenerA)
228stream.addListener(listenerB)
229
230// Stream's Producer does not stop, everything continues as before
231```
232
233It's still useful to eventually (asynchronously) stop a Stream's internal Producer, because you don't want useless computation lying around producing gibberish. At least I don't.
234
235# Factories
236
237Factories are functions that create Streams, such as `xs.create()`, `xs.periodic()`, etc.
238
239### <a id="create"></a> `create(producer)`
240
241Creates a new Stream given a Producer.
242
243#### Arguments:
244
245- `producer: Producer` An optional Producer that dictates how to start, generate events, and stop the Stream.
246
247#### Returns: Stream
248
249- - -
250
251### <a id="createWithMemory"></a> `createWithMemory(producer)`
252
253Creates a new MemoryStream given a Producer.
254
255#### Arguments:
256
257- `producer: Producer` An optional Producer that dictates how to start, generate events, and stop the Stream.
258
259#### Returns: MemoryStream
260
261- - -
262
263### <a id="never"></a> `never()`
264
265Creates a Stream that does nothing when started. It never emits any event.
266
267Marble diagram:
268
269```text
270 never
271-----------------------
272```
273
274#### Returns: Stream
275
276- - -
277
278### <a id="empty"></a> `empty()`
279
280Creates a Stream that immediately emits the "complete" notification when
281started, and that's it.
282
283Marble diagram:
284
285```text
286empty
287-|
288```
289
290#### Returns: Stream
291
292- - -
293
294### <a id="throw"></a> `throw(error)`
295
296Creates a Stream that immediately emits an "error" notification with the
297value you passed as the `error` argument when the stream starts, and that's
298it.
299
300Marble diagram:
301
302```text
303throw(X)
304-X
305```
306
307#### Arguments:
308
309- `error` The error event to emit on the created stream.
310
311#### Returns: Stream
312
313- - -
314
315### <a id="from"></a> `from(input)`
316
317Creates a stream from an Array, Promise, or an Observable.
318
319#### Arguments:
320
321- `input: Array|PromiseLike|Observable` The input to make a stream from.
322
323#### Returns: Stream
324
325- - -
326
327### <a id="of"></a> `of(a, b)`
328
329Creates a Stream that immediately emits the arguments that you give to
330*of*, then completes.
331
332Marble diagram:
333
334```text
335of(1,2,3)
336123|
337```
338
339#### Arguments:
340
341- `a` The first value you want to emit as an event on the stream.
342- `b` The second value you want to emit as an event on the stream. One or more of these values may be given as arguments.
343
344#### Returns: Stream
345
346- - -
347
348### <a id="fromArray"></a> `fromArray(array)`
349
350Converts an array to a stream. The returned stream will emit synchronously
351all the items in the array, and then complete.
352
353Marble diagram:
354
355```text
356fromArray([1,2,3])
357123|
358```
359
360#### Arguments:
361
362- `array: Array` The array to be converted as a stream.
363
364#### Returns: Stream
365
366- - -
367
368### <a id="fromPromise"></a> `fromPromise(promise)`
369
370Converts a promise to a stream. The returned stream will emit the resolved
371value of the promise, and then complete. However, if the promise is
372rejected, the stream will emit the corresponding error.
373
374Marble diagram:
375
376```text
377fromPromise( ----42 )
378-----------------42|
379```
380
381#### Arguments:
382
383- `promise: PromiseLike` The promise to be converted as a stream.
384
385#### Returns: Stream
386
387- - -
388
389### <a id="fromObservable"></a> `fromObservable(observable)`
390
391Converts an Observable into a Stream.
392
393#### Arguments:
394
395- `observable: any` The observable to be converted as a stream.
396
397#### Returns: Stream
398
399- - -
400
401### <a id="periodic"></a> `periodic(period)`
402
403Creates a stream that periodically emits incremental numbers, every
404`period` milliseconds.
405
406Marble diagram:
407
408```text
409 periodic(1000)
410---0---1---2---3---4---...
411```
412
413#### Arguments:
414
415- `period: number` The interval in milliseconds to use as a rate of emission.
416
417#### Returns: Stream
418
419- - -
420
421### <a id="merge"></a> `merge(stream1, stream2)`
422
423Blends multiple streams together, emitting events from all of them
424concurrently.
425
426*merge* takes multiple streams as arguments, and creates a stream that
427behaves like each of the argument streams, in parallel.
428
429Marble diagram:
430
431```text
432--1----2-----3--------4---
433----a-----b----c---d------
434 merge
435--1-a--2--b--3-c---d--4---
436```
437
438#### Arguments:
439
440- `stream1: Stream` A stream to merge together with other streams.
441- `stream2: Stream` A stream to merge together with other streams. Two or more streams may be given as arguments.
442
443#### Returns: Stream
444
445- - -
446
447### <a id="combine"></a> `combine(stream1, stream2)`
448
449Combines multiple input streams together to return a stream whose events
450are arrays that collect the latest events from each input stream.
451
452*combine* internally remembers the most recent event from each of the input
453streams. When any of the input streams emits an event, that event together
454with all the other saved events are combined into an array. That array will
455be emitted on the output stream. It's essentially a way of joining together
456the events from multiple streams.
457
458Marble diagram:
459
460```text
461--1----2-----3--------4---
462----a-----b-----c--d------
463 combine
464----1a-2a-2b-3b-3c-3d-4d--
465```
466
467#### Arguments:
468
469- `stream1: Stream` A stream to combine together with other streams.
470- `stream2: Stream` A stream to combine together with other streams. Multiple streams, not just two, may be given as arguments.
471
472#### Returns: Stream
473
474- - -
475
476
477# Methods and Operators
478
479Methods are functions attached to a Stream instance, like `stream.addListener()`. Operators are also methods, but return a new Stream, leaving the existing Stream unmodified, except for the fact that it has a child Stream attached as Listener.
480
481### <a id="addListener"></a> `addListener(listener)`
482
483Adds a Listener to the Stream.
484
485#### Arguments:
486
487- `listener: Listener`
488
489- - -
490
491### <a id="removeListener"></a> `removeListener(listener)`
492
493Removes a Listener from the Stream, assuming the Listener was added to it.
494
495#### Arguments:
496
497- `listener: Listener\<T>`
498
499- - -
500
501### <a id="subscribe"></a> `subscribe(listener)`
502
503Adds a Listener to the Stream returning a Subscription to remove that
504listener.
505
506#### Arguments:
507
508- `listener: Listener`
509
510#### Returns: Subscription
511
512- - -
513
514### <a id="map"></a> `map(project)`
515
516Transforms each event from the input Stream through a `project` function,
517to get a Stream that emits those transformed events.
518
519Marble diagram:
520
521```text
522--1---3--5-----7------
523 map(i => i * 10)
524--10--30-50----70-----
525```
526
527#### Arguments:
528
529- `project: Function` A function of type `(t: T) => U` that takes event `t` of type `T` from the input Stream and produces an event of type `U`, to
530be emitted on the output Stream.
531
532#### Returns: Stream
533
534- - -
535
536### <a id="mapTo"></a> `mapTo(projectedValue)`
537
538It's like `map`, but transforms each input event to always the same
539constant value on the output Stream.
540
541Marble diagram:
542
543```text
544--1---3--5-----7-----
545 mapTo(10)
546--10--10-10----10----
547```
548
549#### Arguments:
550
551- `projectedValue` A value to emit on the output Stream whenever the input Stream emits any value.
552
553#### Returns: Stream
554
555- - -
556
557### <a id="filter"></a> `filter(passes)`
558
559Only allows events that pass the test given by the `passes` argument.
560
561Each event from the input stream is given to the `passes` function. If the
562function returns `true`, the event is forwarded to the output stream,
563otherwise it is ignored and not forwarded.
564
565Marble diagram:
566
567```text
568--1---2--3-----4-----5---6--7-8--
569 filter(i => i % 2 === 0)
570------2--------4---------6----8--
571```
572
573#### Arguments:
574
575- `passes: Function` A function of type `(t: T) => boolean` that takes an event from the input stream and checks if it passes, by returning a
576boolean.
577
578#### Returns: Stream
579
580- - -
581
582### <a id="take"></a> `take(amount)`
583
584Lets the first `amount` many events from the input stream pass to the
585output stream, then makes the output stream complete.
586
587Marble diagram:
588
589```text
590--a---b--c----d---e--
591 take(3)
592--a---b--c|
593```
594
595#### Arguments:
596
597- `amount: number` How many events to allow from the input stream before completing the output stream.
598
599#### Returns: Stream
600
601- - -
602
603### <a id="drop"></a> `drop(amount)`
604
605Ignores the first `amount` many events from the input stream, and then
606after that starts forwarding events from the input stream to the output
607stream.
608
609Marble diagram:
610
611```text
612--a---b--c----d---e--
613 drop(3)
614--------------d---e--
615```
616
617#### Arguments:
618
619- `amount: number` How many events to ignore from the input stream before forwarding all events from the input stream to the output stream.
620
621#### Returns: Stream
622
623- - -
624
625### <a id="last"></a> `last()`
626
627When the input stream completes, the output stream will emit the last event
628emitted by the input stream, and then will also complete.
629
630Marble diagram:
631
632```text
633--a---b--c--d----|
634 last()
635-----------------d|
636```
637
638#### Returns: Stream
639
640- - -
641
642### <a id="startWith"></a> `startWith(initial)`
643
644Prepends the given `initial` value to the sequence of events emitted by the
645input stream. The returned stream is a MemoryStream, which means it is
646already `remember()`'d.
647
648Marble diagram:
649
650```text
651---1---2-----3---
652 startWith(0)
6530--1---2-----3---
654```
655
656#### Arguments:
657
658- `initial` The value or event to prepend.
659
660#### Returns: MemoryStream
661
662- - -
663
664### <a id="endWhen"></a> `endWhen(other)`
665
666Uses another stream to determine when to complete the current stream.
667
668When the given `other` stream emits an event or completes, the output
669stream will complete. Before that happens, the output stream will behaves
670like the input stream.
671
672Marble diagram:
673
674```text
675---1---2-----3--4----5----6---
676 endWhen( --------a--b--| )
677---1---2-----3--4--|
678```
679
680#### Arguments:
681
682- `other` Some other stream that is used to know when should the output stream of this operator complete.
683
684#### Returns: Stream
685
686- - -
687
688### <a id="fold"></a> `fold(accumulate, seed)`
689
690"Folds" the stream onto itself.
691
692Combines events from the past throughout
693the entire execution of the input stream, allowing you to accumulate them
694together. It's essentially like `Array.prototype.reduce`. The returned
695stream is a MemoryStream, which means it is already `remember()`'d.
696
697The output stream starts by emitting the `seed` which you give as argument.
698Then, when an event happens on the input stream, it is combined with that
699seed value through the `accumulate` function, and the output value is
700emitted on the output stream. `fold` remembers that output value as `acc`
701("accumulator"), and then when a new input event `t` happens, `acc` will be
702combined with that to produce the new `acc` and so forth.
703
704Marble diagram:
705
706```text
707------1-----1--2----1----1------
708 fold((acc, x) => acc + x, 3)
7093-----4-----5--7----8----9------
710```
711
712#### Arguments:
713
714- `accumulate: Function` A function of type `(acc: R, t: T) => R` that takes the previous accumulated value `acc` and the incoming event from the
715input stream and produces the new accumulated value.
716- `seed` The initial accumulated value, of type `R`.
717
718#### Returns: MemoryStream
719
720- - -
721
722### <a id="replaceError"></a> `replaceError(replace)`
723
724Replaces an error with another stream.
725
726When (and if) an error happens on the input stream, instead of forwarding
727that error to the output stream, *replaceError* will call the `replace`
728function which returns the stream that the output stream will replicate.
729And, in case that new stream also emits an error, `replace` will be called
730again to get another stream to start replicating.
731
732Marble diagram:
733
734```text
735--1---2-----3--4-----X
736 replaceError( () => --10--| )
737--1---2-----3--4--------10--|
738```
739
740#### Arguments:
741
742- `replace: Function` A function of type `(err) => Stream` that takes the error that occurred on the input stream or on the previous replacement
743stream and returns a new stream. The output stream will behave like the
744stream that this function returns.
745
746#### Returns: Stream
747
748- - -
749
750### <a id="flatten"></a> `flatten()`
751
752Flattens a "stream of streams", handling only one nested stream at a time
753(no concurrency).
754
755If the input stream is a stream that emits streams, then this operator will
756return an output stream which is a flat stream: emits regular events. The
757flattening happens without concurrency. It works like this: when the input
758stream emits a nested stream, *flatten* will start imitating that nested
759one. However, as soon as the next nested stream is emitted on the input
760stream, *flatten* will forget the previous nested one it was imitating, and
761will start imitating the new nested one.
762
763Marble diagram:
764
765```text
766--+--------+---------------
767 \ \
768 \ ----1----2---3--
769 --a--b----c----d--------
770 flatten
771-----a--b------1----2---3--
772```
773
774#### Returns: Stream
775
776- - -
777
778### <a id="compose"></a> `compose(operator)`
779
780Passes the input stream to a custom operator, to produce an output stream.
781
782*compose* is a handy way of using an existing function in a chained style.
783Instead of writing `outStream = f(inStream)` you can write
784`outStream = inStream.compose(f)`.
785
786#### Arguments:
787
788- `operator: function` A function that takes a stream as input and returns a stream as well.
789
790#### Returns: Stream
791
792- - -
793
794### <a id="remember"></a> `remember()`
795
796Returns an output stream that behaves like the input stream, but also
797remembers the most recent event that happens on the input stream, so that a
798newly added listener will immediately receive that memorised event.
799
800#### Returns: MemoryStream
801
802- - -
803
804### <a id="debug"></a> `debug(labelOrSpy)`
805
806Returns an output stream that identically behaves like the input stream,
807but also runs a `spy` function for each event, to help you debug your app.
808
809*debug* takes a `spy` function as argument, and runs that for each event
810happening on the input stream. If you don't provide the `spy` argument,
811then *debug* will just `console.log` each event. This helps you to
812understand the flow of events through some operator chain.
813
814Please note that if the output stream has no listeners, then it will not
815start, which means `spy` will never run because no actual event happens in
816that case.
817
818Marble diagram:
819
820```text
821--1----2-----3-----4--
822 debug
823--1----2-----3-----4--
824```
825
826#### Arguments:
827
828- `labelOrSpy: function` A string to use as the label when printing debug information on the console, or a 'spy' function that takes an event
829as argument, and does not need to return anything.
830
831#### Returns: Stream
832
833- - -
834
835### <a id="imitate"></a> `imitate(target)`
836
837*imitate* changes this current Stream to emit the same events that the
838`other` given Stream does. This method returns nothing.
839
840This method exists to allow one thing: **circular dependency of streams**.
841For instance, let's imagine that for some reason you need to create a
842circular dependency where stream `first$` depends on stream `second$`
843which in turn depends on `first$`:
844
845<!-- skip-example -->
846```js
847import delay from 'xstream/extra/delay'
848
849var first$ = second$.map(x => x * 10).take(3);
850var second$ = first$.map(x => x + 1).startWith(1).compose(delay(100));
851```
852
853However, that is invalid JavaScript, because `second$` is undefined
854on the first line. This is how *imitate* can help solve it:
855
856```js
857import delay from 'xstream/extra/delay'
858
859var secondProxy$ = xs.create();
860var first$ = secondProxy$.map(x => x * 10).take(3);
861var second$ = first$.map(x => x + 1).startWith(1).compose(delay(100));
862secondProxy$.imitate(second$);
863```
864
865We create `secondProxy$` before the others, so it can be used in the
866declaration of `first$`. Then, after both `first$` and `second$` are
867defined, we hook `secondProxy$` with `second$` with `imitate()` to tell
868that they are "the same". `imitate` will not trigger the start of any
869stream, it just binds `secondProxy$` and `second$` together.
870
871The following is an example where `imitate()` is important in Cycle.js
872applications. A parent component contains some child components. A child
873has an action stream which is given to the parent to define its state:
874
875<!-- skip-example -->
876```js
877const childActionProxy$ = xs.create();
878const parent = Parent({...sources, childAction$: childActionProxy$});
879const childAction$ = parent.state$.map(s => s.child.action$).flatten();
880childActionProxy$.imitate(childAction$);
881```
882
883Note, though, that **`imitate()` does not support MemoryStreams**. If we
884would attempt to imitate a MemoryStream in a circular dependency, we would
885either get a race condition (where the symptom would be "nothing happens")
886or an infinite cyclic emission of values. It's useful to think about
887MemoryStreams as cells in a spreadsheet. It doesn't make any sense to
888define a spreadsheet cell `A1` with a formula that depends on `B1` and
889cell `B1` defined with a formula that depends on `A1`.
890
891If you find yourself wanting to use `imitate()` with a
892MemoryStream, you should rework your code around `imitate()` to use a
893Stream instead. Look for the stream in the circular dependency that
894represents an event stream, and that would be a candidate for creating a
895proxy Stream which then imitates the target Stream.
896
897#### Arguments:
898
899- `target: Stream` The other stream to imitate on the current one. Must not be a MemoryStream.
900
901- - -
902
903### <a id="shamefullySendNext"></a> `shamefullySendNext(value)`
904
905Forces the Stream to emit the given value to its listeners.
906
907As the name indicates, if you use this, you are most likely doing something
908The Wrong Way. Please try to understand the reactive way before using this
909method. Use it only when you know what you are doing.
910
911#### Arguments:
912
913- `value` The "next" value you want to broadcast to all listeners of this Stream.
914
915- - -
916
917### <a id="shamefullySendError"></a> `shamefullySendError(error)`
918
919Forces the Stream to emit the given error to its listeners.
920
921As the name indicates, if you use this, you are most likely doing something
922The Wrong Way. Please try to understand the reactive way before using this
923method. Use it only when you know what you are doing.
924
925#### Arguments:
926
927- `error: any` The error you want to broadcast to all the listeners of this Stream.
928
929- - -
930
931### <a id="shamefullySendComplete"></a> `shamefullySendComplete()`
932
933Forces the Stream to emit the "completed" event to its listeners.
934
935As the name indicates, if you use this, you are most likely doing something
936The Wrong Way. Please try to understand the reactive way before using this
937method. Use it only when you know what you are doing.
938
939- - -
940
941### <a id="setDebugListener"></a> `setDebugListener(listener)`
942
943Adds a "debug" listener to the stream. There can only be one debug
944listener, that's why this is 'setDebugListener'. To remove the debug
945listener, just call setDebugListener(null).
946
947A debug listener is like any other listener. The only difference is that a
948debug listener is "stealthy": its presence/absence does not trigger the
949start/stop of the stream (or the producer inside the stream). This is
950useful so you can inspect what is going on without changing the behavior
951of the program. If you have an idle stream and you add a normal listener to
952it, the stream will start executing. But if you set a debug listener on an
953idle stream, it won't start executing (not until the first normal listener
954is added).
955
956As the name indicates, we don't recommend using this method to build app
957logic. In fact, in most cases the debug operator works just fine. Only use
958this one if you know what you're doing.
959
960#### Arguments:
961
962- `listener: Listener\<T>`
963
964- - -
965
966# FAQ
967
968**Q: Why does `imitate()` support a Stream but not a MemoryStream?**
969
970A: MemoryStreams are meant for representing "values over time" (your age), while Streams represent simply events (your birthdays). MemoryStreams are usually initialized with a value, and `imitate()` is meant for creating circular dependencies of streams. If we would attempt to imitate a MemoryStream in a circular dependency, we would either get a race condition (where the symptom would be "nothing happens") or an infinite cyclic emission of values.
971
972If you find yourself wanting to use `imitate()` with a MemoryStream, you should rework your code around `imitate()` to use a Stream instead. Look for the stream in the circular dependency that represents an event stream, and that would be a candidate for creating a MimicStream which then imitates the real event stream.
973
974**Q: What's the difference between xstream and RxJS?**
975
976A: Read this [blog post](http://staltz.com/why-we-built-xstream.html) on the topic. In short:
977
978- xstream Streams are multicast always.
979- RxJS Observables are unicast by default, and opt-in multicast.
980- xstream has few operators *as a feature* (helps against decision paralysis).
981- RxJS has many operators *as a feature* (helps for flexibility and power).
982
983**Q: What is the equivalent of [`withLatestFrom`](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-withLatestFrom) in xstream?**
984
985A: `withLatestFrom` is implemented as an extra named [`sampleCombine`](https://github.com/staltz/xstream/blob/master/EXTRA_DOCS.md#sampleCombine).
986
987-----
988
989# Misc.
990
991## Acknowledgements
992
993*xstream* is built by [staltz](https://github.com/staltz) and [TylorS](https://github.com/tylors).
994
995## CHANGELOG
996
997Read the [CHANGELOG](https://github.com/staltz/xstream/blob/master/CHANGELOG.md) for release notes of all versions of *xstream*.
998
999## License
1000
1001[MIT](https://github.com/staltz/xstream/blob/master/LICENSE)