Comparing version 4.0.4 to 5.0.2
@@ -0,1 +1,34 @@ | ||
<a name="5.0.2"></a> | ||
## [5.0.2](https://github.com/staltz/xstream/compare/v4.0.4...v5.0.2) (2016-06-12) | ||
### Bug Fixes | ||
* **imitate:** fix cyclic execution leak, and refactor ([8a432b6](https://github.com/staltz/xstream/commit/8a432b6)), closes [#51](https://github.com/staltz/xstream/issues/51) [#49](https://github.com/staltz/xstream/issues/49) | ||
* **take:** remove redundant stop() call ([625fb3e](https://github.com/staltz/xstream/commit/625fb3e)) | ||
### Features | ||
* **combine:** change API for combine() operator ([a2aa0a6](https://github.com/staltz/xstream/commit/a2aa0a6)) | ||
* **imitate:** move imitate() from MimicStream to Stream ([ad63372](https://github.com/staltz/xstream/commit/ad63372)) | ||
### BREAKING CHANGES | ||
* combine: combine() now takes only streams as argument, no more project function. combine() will return an | ||
stream that emits arrays of the collected values from each input stream. To transform that array, | ||
you should now use map() operator after combine(), to take the array of collected values and return | ||
a combination value. See tests for examples. | ||
* imitate: MimicStream and xs.createMimic() were removed entirely. The imitate() method now exists on every | ||
Stream instance. To use the proxy stream technique, use xs.create() to create the proxy, then call | ||
proxy.imitate(other). | ||
<a name="4.0.4"></a> | ||
## [4.0.4](https://github.com/staltz/xstream/compare/v4.0.3...v4.0.4) (2016-06-09) | ||
<a name="4.0.3"></a> | ||
@@ -39,5 +72,6 @@ ## [4.0.3](https://github.com/staltz/xstream/compare/v4.0.2...v4.0.3) (2016-06-08) | ||
### Features | ||
* **core:** improve signature of operators regarding types (#43) ([116e9f2](https://github.com/staltz/xstream/commit/116e9f2)) | ||
* **core:** improve signature of operators regarding types ([#43](https://github.com/staltz/xstream/issues/43)) ([116e9f2](https://github.com/staltz/xstream/commit/116e9f2)) | ||
@@ -135,2 +169,3 @@ | ||
### Performance Improvements | ||
@@ -171,2 +206,3 @@ | ||
### Features | ||
@@ -187,2 +223,3 @@ | ||
### Features | ||
@@ -222,2 +259,3 @@ | ||
### Performance Improvements | ||
@@ -268,2 +306,3 @@ | ||
### Features | ||
@@ -283,2 +322,3 @@ | ||
### Performance Improvements | ||
@@ -338,2 +378,3 @@ | ||
### Features | ||
@@ -370,2 +411,3 @@ | ||
### Features | ||
@@ -422,2 +464,3 @@ | ||
### Performance Improvements | ||
@@ -444,2 +487,3 @@ | ||
### Reverts | ||
@@ -446,0 +490,0 @@ |
198
core.d.ts
@@ -29,16 +29,23 @@ export interface InternalListener<T> { | ||
} | ||
export interface CombineProjectFunction { | ||
<T1, T2, R>(v1: T1, v2: T2): R; | ||
<T1, T2, T3, R>(v1: T1, v2: T2, v3: T3): R; | ||
<T1, T2, T3, T4, R>(v1: T1, v2: T2, v3: T3, v4: T4): R; | ||
<T1, T2, T3, T4, T5, R>(v1: T1, v2: T2, v3: T3, v4: T4, v5: T5): R; | ||
<T1, T2, T3, T4, T5, T6, R>(v1: T1, v2: T2, v3: T3, v4: T4, v5: T5, v6: T6): R; | ||
<R>(...values: Array<any>): R; | ||
export declare class MergeProducer<T> implements InternalProducer<T>, InternalListener<T> { | ||
streams: Array<Stream<T>>; | ||
type: string; | ||
private out; | ||
private ac; | ||
constructor(streams: Array<Stream<T>>); | ||
_start(out: InternalListener<T>): void; | ||
_stop(): void; | ||
_n(t: T): void; | ||
_e(err: any): void; | ||
_c(): void; | ||
} | ||
export interface CombineFactorySignature { | ||
<T1, T2, R>(project: (t1: T1, t2: T2) => R, stream1: Stream<T1>, stream2: Stream<T2>): Stream<R>; | ||
<T1, T2, T3, R>(project: (t1: T1, t2: T2, t3: T3) => R, stream1: Stream<T1>, stream2: Stream<T2>, stream3: Stream<T3>): Stream<R>; | ||
<T1, T2, T3, T4, R>(project: (t1: T1, t2: T2, t3: T3, t4: T4) => R, stream1: Stream<T1>, stream2: Stream<T2>, stream3: Stream<T3>, stream4: Stream<T4>): Stream<R>; | ||
<T1, T2, T3, T4, T5, R>(project: (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5) => R, stream1: Stream<T1>, stream2: Stream<T2>, stream3: Stream<T3>, stream4: Stream<T4>, stream5: Stream<T5>): Stream<R>; | ||
<R>(project: (...args: Array<any>) => R, ...streams: Array<Stream<any>>): Stream<R>; | ||
export interface CombineSignature { | ||
(): Stream<Array<any>>; | ||
<T1>(s1: Stream<T1>): Stream<[T1]>; | ||
<T1, T2>(s1: Stream<T1>, s2: Stream<T2>): Stream<[T1, T2]>; | ||
<T1, T2, T3>(s1: Stream<T1>, s2: Stream<T2>, s3: Stream<T3>): Stream<[T1, T2, T3]>; | ||
<T1, T2, T3, T4>(s1: Stream<T1>, s2: Stream<T2>, s3: Stream<T3>, s4: Stream<T4>): Stream<[T1, T2, T3, T4]>; | ||
<T1, T2, T3, T4, T5>(s1: Stream<T1>, s2: Stream<T2>, s3: Stream<T3>, s4: Stream<T4>, s5: Stream<T5>): Stream<[T1, T2, T3, T4, T5]>; | ||
<T1, T2, T3, T4, T5, T6>(s1: Stream<T1>, s2: Stream<T2>, s3: Stream<T3>, s4: Stream<T4>, s5: Stream<T5>, s6: Stream<T6>): Stream<[T1, T2, T3, T4, T5, T6]>; | ||
(...stream: Array<Stream<any>>): Stream<Array<any>>; | ||
} | ||
@@ -53,16 +60,14 @@ export declare class CombineListener<T> implements InternalListener<T> { | ||
} | ||
export declare class CombineProducer<R> implements InternalProducer<R> { | ||
project: CombineProjectFunction; | ||
export declare class CombineProducer<R> implements InternalProducer<Array<R>> { | ||
streams: Array<Stream<any>>; | ||
type: string; | ||
out: InternalListener<R>; | ||
out: InternalListener<Array<R>>; | ||
ils: Array<CombineListener<any>>; | ||
ac: number; | ||
left: number; | ||
vals: Array<any>; | ||
constructor(project: CombineProjectFunction, streams: Array<Stream<any>>); | ||
vals: Array<R>; | ||
constructor(streams: Array<Stream<any>>); | ||
up(t: any, i: number): boolean; | ||
_start(out: InternalListener<R>): void; | ||
_start(out: InternalListener<Array<R>>): void; | ||
_stop(): void; | ||
zero(out: InternalListener<R>): void; | ||
} | ||
@@ -84,14 +89,2 @@ export declare class FromArrayProducer<T> implements InternalProducer<T> { | ||
} | ||
export declare class MergeProducer<T> implements InternalProducer<T>, InternalListener<T> { | ||
streams: Array<Stream<T>>; | ||
type: string; | ||
private out; | ||
private ac; | ||
constructor(streams: Array<Stream<T>>); | ||
_start(out: InternalListener<T>): void; | ||
_stop(): void; | ||
_n(t: T): void; | ||
_e(err: any): void; | ||
_c(): void; | ||
} | ||
export declare class PeriodicProducer implements InternalProducer<number> { | ||
@@ -270,2 +263,3 @@ period: number; | ||
protected _ils: Array<InternalListener<T>>; | ||
protected _hil: InternalListener<T>; | ||
protected _stopID: any; | ||
@@ -292,2 +286,3 @@ protected _prod: InternalProducer<T>; | ||
_remove(il: InternalListener<T>): void; | ||
_setHIL(il: InternalListener<T>): void; | ||
private ctor(); | ||
@@ -313,10 +308,2 @@ /** | ||
/** | ||
* Creates a new MimicStream, which can `imitate` another Stream. Only a | ||
* MimicStream has the `imitate()` method. | ||
* | ||
* @factory true | ||
* @return {MimicStream} | ||
*/ | ||
static createMimic<T>(): MimicStream<T>; | ||
/** | ||
* Creates a Stream that does nothing when started. It never emits any event. | ||
@@ -459,11 +446,10 @@ * | ||
/** | ||
* Combines multiple streams together to return a stream whose events are | ||
* calculated from the latest events of each of the input streams. | ||
* Combines multiple input streams together to return a stream whose events | ||
* are arrays that collect the latest events from each input stream. | ||
* | ||
* *combine* remembers the most recent event from each of the input streams. | ||
* When any of the input streams emits an event, that event together with all | ||
* the other saved events are combined in the `project` function which should | ||
* return a value. That value will be emitted on the output stream. It's | ||
* essentially a way of mixing the events from multiple streams according to a | ||
* formula. | ||
* *combine* internally remembers the most recent event from each of the input | ||
* streams. When any of the input streams emits an event, that event together | ||
* with all the other saved events are combined into an array. That array will | ||
* be emitted on the output stream. It's essentially a way of joining together | ||
* the events from multiple streams. | ||
* | ||
@@ -475,3 +461,3 @@ * Marble diagram: | ||
* ----a-----b-----c--d------ | ||
* combine((x,y) => x+y) | ||
* combine | ||
* ----1a-2a-2b-3b-3c-3d-4d-- | ||
@@ -481,13 +467,8 @@ * ``` | ||
* @factory true | ||
* @param {Function} project A function of type `(x: T1, y: T2) => R` or | ||
* similar that takes the most recent events `x` and `y` from the input | ||
* streams and returns a value. The output stream will emit that value. The | ||
* number of arguments for this function should match the number of input | ||
* streams. | ||
* @param {Stream} stream1 A stream to combine together with other streams. | ||
* @param {Stream} stream2 A stream to combine together with other streams. | ||
* Two or more streams may be given as arguments. | ||
* Multiple streams, not just two, may be given as arguments. | ||
* @return {Stream} | ||
*/ | ||
static combine: CombineFactorySignature; | ||
static combine: CombineSignature; | ||
protected _map<U>(project: (t: T) => U): Stream<U> | MemoryStream<U>; | ||
@@ -765,47 +746,10 @@ /** | ||
/** | ||
* Forces the Stream to emit the given value to its listeners. | ||
* *imitate* changes this current Stream to emit the same events that the | ||
* `other` given Stream does. This method returns nothing. | ||
* | ||
* As the name indicates, if you use this, you are most likely doing something | ||
* The Wrong Way. Please try to understand the reactive way before using this | ||
* method. Use it only when you know what you are doing. | ||
* This method exists to allow one thing: **circular dependency of streams**. | ||
* For instance, let's imagine that for some reason you need to create a | ||
* circular dependency where stream `first$` depends on stream `second$` | ||
* which in turn depends on `first$`: | ||
* | ||
* @param value The "next" value you want to broadcast to all listeners of | ||
* this Stream. | ||
*/ | ||
shamefullySendNext(value: T): void; | ||
/** | ||
* Forces the Stream to emit the given error to its listeners. | ||
* | ||
* As the name indicates, if you use this, you are most likely doing something | ||
* The Wrong Way. Please try to understand the reactive way before using this | ||
* method. Use it only when you know what you are doing. | ||
* | ||
* @param {any} error The error you want to broadcast to all the listeners of | ||
* this Stream. | ||
*/ | ||
shamefullySendError(error: any): void; | ||
/** | ||
* Forces the Stream to emit the "completed" event to its listeners. | ||
* | ||
* As the name indicates, if you use this, you are most likely doing something | ||
* The Wrong Way. Please try to understand the reactive way before using this | ||
* method. Use it only when you know what you are doing. | ||
*/ | ||
shamefullySendComplete(): void; | ||
} | ||
export declare class MimicStream<T> extends Stream<T> { | ||
private _target; | ||
constructor(); | ||
_add(il: InternalListener<T>): void; | ||
_remove(il: InternalListener<T>): void; | ||
/** | ||
* This method exists only on a MimicStream, which is created through | ||
* `xs.createMimic()`. *imitate* changes this current MimicStream to behave | ||
* like the `other` given stream. | ||
* | ||
* The `imitate` method and the `MimicStream` type exist to allow one thing: | ||
* **circular dependency of streams**. For instance, let's imagine that for | ||
* some reason you need to create a circular dependency where stream `first$` | ||
* depends on stream `second$` which in turn depends on `first$`: | ||
* | ||
* <!-- skip-example --> | ||
@@ -820,3 +764,3 @@ * ```js | ||
* However, that is invalid JavaScript, because `second$` is undefined | ||
* on the first line. This is how a MimicStream and imitate can help solve it: | ||
* on the first line. This is how *imitate* can help solve it: | ||
* | ||
@@ -826,13 +770,13 @@ * ```js | ||
* | ||
* var secondMimic$ = xs.createMimic(); | ||
* var first$ = secondMimic$.map(x => x * 10).take(3); | ||
* var secondProxy$ = xs.create(); | ||
* var first$ = secondProxy$.map(x => x * 10).take(3); | ||
* var second$ = first$.map(x => x + 1).startWith(1).compose(delay(100)); | ||
* secondMimic$.imitate(second$); | ||
* secondProxy$.imitate(second$); | ||
* ``` | ||
* | ||
* We create `secondMimic$` before the others, so it can be used in the | ||
* We create `secondProxy$` before the others, so it can be used in the | ||
* declaration of `first$`. Then, after both `first$` and `second$` are | ||
* defined, we hook `secondMimic$` with `second$` with `imitate()` to tell | ||
* defined, we hook `secondProxy$` with `second$` with `imitate()` to tell | ||
* that they are "the same". `imitate` will not trigger the start of any | ||
* stream, it simply forwards listeners of `secondMimic$` to `second$`. | ||
* stream, it just binds `secondProxy$` and `second$` together. | ||
* | ||
@@ -845,12 +789,8 @@ * The following is an example where `imitate()` is important in Cycle.js | ||
* ```js | ||
* const childActionMimic$ = xs.createMimic(); | ||
* const parent = Parent({...sources, childAction$: childActionMimic$}); | ||
* const childActionProxy$ = xs.create(); | ||
* const parent = Parent({...sources, childAction$: childActionProxy$}); | ||
* const childAction$ = parent.state$.map(s => s.child.action$).flatten(); | ||
* childActionMimic$.imitate(childAction$); | ||
* childActionProxy$.imitate(childAction$); | ||
* ``` | ||
* | ||
* The *imitate* method returns nothing. Instead, it changes the behavior of | ||
* the current stream, making it re-emit whatever events are emitted by the | ||
* given `other` stream. | ||
* | ||
* Note, though, that **`imitate()` does not support MemoryStreams**. If we | ||
@@ -868,3 +808,3 @@ * would attempt to imitate a MemoryStream in a circular dependency, we would | ||
* represents an event stream, and that would be a candidate for creating a | ||
* MimicStream which then imitates the real event stream. | ||
* proxy Stream which then imitates the target Stream. | ||
* | ||
@@ -875,2 +815,32 @@ * @param {Stream} other The stream to imitate on the current one. Must not be | ||
imitate(other: Stream<T>): void; | ||
/** | ||
* Forces the Stream to emit the given value to its listeners. | ||
* | ||
* As the name indicates, if you use this, you are most likely doing something | ||
* The Wrong Way. Please try to understand the reactive way before using this | ||
* method. Use it only when you know what you are doing. | ||
* | ||
* @param value The "next" value you want to broadcast to all listeners of | ||
* this Stream. | ||
*/ | ||
shamefullySendNext(value: T): void; | ||
/** | ||
* Forces the Stream to emit the given error to its listeners. | ||
* | ||
* As the name indicates, if you use this, you are most likely doing something | ||
* The Wrong Way. Please try to understand the reactive way before using this | ||
* method. Use it only when you know what you are doing. | ||
* | ||
* @param {any} error The error you want to broadcast to all the listeners of | ||
* this Stream. | ||
*/ | ||
shamefullySendError(error: any): void; | ||
/** | ||
* Forces the Stream to emit the "completed" event to its listeners. | ||
* | ||
* As the name indicates, if you use this, you are most likely doing something | ||
* The Wrong Way. Please try to understand the reactive way before using this | ||
* method. Use it only when you know what you are doing. | ||
*/ | ||
shamefullySendComplete(): void; | ||
} | ||
@@ -877,0 +847,0 @@ export declare class MemoryStream<T> extends Stream<T> { |
355
core.js
@@ -33,13 +33,2 @@ "use strict"; | ||
} | ||
function invoke(f, args) { | ||
switch (args.length) { | ||
case 0: return f(); | ||
case 1: return f(args[0]); | ||
case 2: return f(args[0], args[1]); | ||
case 3: return f(args[0], args[1], args[2]); | ||
case 4: return f(args[0], args[1], args[2], args[3]); | ||
case 5: return f(args[0], args[1], args[2], args[3], args[4]); | ||
default: return f.apply(void 0, args); | ||
} | ||
} | ||
function compose2(f1, f2) { | ||
@@ -55,2 +44,49 @@ return function composedFn(arg) { | ||
} | ||
var MergeProducer = (function () { | ||
function MergeProducer(streams) { | ||
this.streams = streams; | ||
this.type = 'merge'; | ||
this.out = exports.emptyListener; | ||
this.ac = streams.length; | ||
} | ||
MergeProducer.prototype._start = function (out) { | ||
this.out = out; | ||
var s = this.streams; | ||
var L = s.length; | ||
for (var i = 0; i < L; i++) { | ||
s[i]._add(this); | ||
} | ||
}; | ||
MergeProducer.prototype._stop = function () { | ||
var s = this.streams; | ||
var L = s.length; | ||
for (var i = 0; i < L; i++) { | ||
s[i]._remove(this); | ||
} | ||
this.out = null; | ||
this.ac = L; | ||
}; | ||
MergeProducer.prototype._n = function (t) { | ||
var u = this.out; | ||
if (!u) | ||
return; | ||
u._n(t); | ||
}; | ||
MergeProducer.prototype._e = function (err) { | ||
var u = this.out; | ||
if (!u) | ||
return; | ||
u._e(err); | ||
}; | ||
MergeProducer.prototype._c = function () { | ||
if (--this.ac === 0) { | ||
var u = this.out; | ||
if (!u) | ||
return; | ||
u._c(); | ||
} | ||
}; | ||
return MergeProducer; | ||
}()); | ||
exports.MergeProducer = MergeProducer; | ||
var CombineListener = (function () { | ||
@@ -67,8 +103,3 @@ function CombineListener(i, p) { | ||
if (p.up(t, this.i)) { | ||
try { | ||
out._n(invoke(p.project, p.vals)); | ||
} | ||
catch (e) { | ||
out._e(e); | ||
} | ||
out._n(p.vals); | ||
} | ||
@@ -94,4 +125,3 @@ }; | ||
var CombineProducer = (function () { | ||
function CombineProducer(project, streams) { | ||
this.project = project; | ||
function CombineProducer(streams) { | ||
this.streams = streams; | ||
@@ -117,4 +147,6 @@ this.type = 'combine'; | ||
var n = s.length; | ||
if (n === 0) | ||
this.zero(out); | ||
if (n === 0) { | ||
out._n(this.vals); | ||
out._c(); | ||
} | ||
else { | ||
@@ -137,11 +169,2 @@ for (var i = 0; i < n; i++) { | ||
}; | ||
CombineProducer.prototype.zero = function (out) { | ||
try { | ||
out._n(this.project()); | ||
out._c(); | ||
} | ||
catch (e) { | ||
out._e(e); | ||
} | ||
}; | ||
return CombineProducer; | ||
@@ -193,49 +216,2 @@ }()); | ||
exports.FromPromiseProducer = FromPromiseProducer; | ||
var MergeProducer = (function () { | ||
function MergeProducer(streams) { | ||
this.streams = streams; | ||
this.type = 'merge'; | ||
this.out = exports.emptyListener; | ||
this.ac = streams.length; | ||
} | ||
MergeProducer.prototype._start = function (out) { | ||
this.out = out; | ||
var s = this.streams; | ||
var L = s.length; | ||
for (var i = 0; i < L; i++) { | ||
s[i]._add(this); | ||
} | ||
}; | ||
MergeProducer.prototype._stop = function () { | ||
var s = this.streams; | ||
var L = s.length; | ||
for (var i = 0; i < L; i++) { | ||
s[i]._remove(this); | ||
} | ||
this.out = null; | ||
this.ac = L; | ||
}; | ||
MergeProducer.prototype._n = function (t) { | ||
var u = this.out; | ||
if (!u) | ||
return; | ||
u._n(t); | ||
}; | ||
MergeProducer.prototype._e = function (err) { | ||
var u = this.out; | ||
if (!u) | ||
return; | ||
u._e(err); | ||
}; | ||
MergeProducer.prototype._c = function () { | ||
if (--this.ac === 0) { | ||
var u = this.out; | ||
if (!u) | ||
return; | ||
u._c(); | ||
} | ||
}; | ||
return MergeProducer; | ||
}()); | ||
exports.MergeProducer = MergeProducer; | ||
var PeriodicProducer = (function () { | ||
@@ -833,3 +809,2 @@ function PeriodicProducer(period) { | ||
u._c(); | ||
this._stop(); | ||
} | ||
@@ -857,2 +832,3 @@ }; | ||
this._ils = []; | ||
this._hil = null; | ||
} | ||
@@ -869,2 +845,5 @@ Stream.prototype._n = function (t) { | ||
} | ||
var h = this._hil; | ||
if (h) | ||
h._n(t); | ||
}; | ||
@@ -881,2 +860,5 @@ Stream.prototype._e = function (err) { | ||
} | ||
var h = this._hil; | ||
if (h) | ||
h._e(err); | ||
this._x(); | ||
@@ -894,2 +876,5 @@ }; | ||
} | ||
var h = this._hil; | ||
if (h) | ||
h._c(); | ||
this._x(); | ||
@@ -953,2 +938,5 @@ }; | ||
}; | ||
Stream.prototype._setHIL = function (il) { | ||
this._hil = il; | ||
}; | ||
Stream.prototype.ctor = function () { | ||
@@ -990,12 +978,2 @@ return this instanceof MemoryStream ? MemoryStream : Stream; | ||
/** | ||
* Creates a new MimicStream, which can `imitate` another Stream. Only a | ||
* MimicStream has the `imitate()` method. | ||
* | ||
* @factory true | ||
* @return {MimicStream} | ||
*/ | ||
Stream.createMimic = function () { | ||
return new MimicStream(); | ||
}; | ||
/** | ||
* Creates a Stream that does nothing when started. It never emits any event. | ||
@@ -1502,2 +1480,74 @@ * | ||
/** | ||
* *imitate* changes this current Stream to emit the same events that the | ||
* `other` given Stream does. This method returns nothing. | ||
* | ||
* This method exists to allow one thing: **circular dependency of streams**. | ||
* For instance, let's imagine that for some reason you need to create a | ||
* circular dependency where stream `first$` depends on stream `second$` | ||
* which in turn depends on `first$`: | ||
* | ||
* <!-- skip-example --> | ||
* ```js | ||
* import delay from 'xstream/extra/delay' | ||
* | ||
* var first$ = second$.map(x => x * 10).take(3); | ||
* var second$ = first$.map(x => x + 1).startWith(1).compose(delay(100)); | ||
* ``` | ||
* | ||
* However, that is invalid JavaScript, because `second$` is undefined | ||
* on the first line. This is how *imitate* can help solve it: | ||
* | ||
* ```js | ||
* import delay from 'xstream/extra/delay' | ||
* | ||
* var secondProxy$ = xs.create(); | ||
* var first$ = secondProxy$.map(x => x * 10).take(3); | ||
* var second$ = first$.map(x => x + 1).startWith(1).compose(delay(100)); | ||
* secondProxy$.imitate(second$); | ||
* ``` | ||
* | ||
* We create `secondProxy$` before the others, so it can be used in the | ||
* declaration of `first$`. Then, after both `first$` and `second$` are | ||
* defined, we hook `secondProxy$` with `second$` with `imitate()` to tell | ||
* that they are "the same". `imitate` will not trigger the start of any | ||
* stream, it just binds `secondProxy$` and `second$` together. | ||
* | ||
* The following is an example where `imitate()` is important in Cycle.js | ||
* applications. A parent component contains some child components. A child | ||
* has an action stream which is given to the parent to define its state: | ||
* | ||
* <!-- skip-example --> | ||
* ```js | ||
* const childActionProxy$ = xs.create(); | ||
* const parent = Parent({...sources, childAction$: childActionProxy$}); | ||
* const childAction$ = parent.state$.map(s => s.child.action$).flatten(); | ||
* childActionProxy$.imitate(childAction$); | ||
* ``` | ||
* | ||
* Note, though, that **`imitate()` does not support MemoryStreams**. 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. It's useful to think about | ||
* MemoryStreams as cells in a spreadsheet. It doesn't make any sense to | ||
* define a spreadsheet cell `A1` with a formula that depends on `B1` and | ||
* cell `B1` defined with a formula that depends on `A1`. | ||
* | ||
* If 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 | ||
* proxy Stream which then imitates the target Stream. | ||
* | ||
* @param {Stream} other The stream to imitate on the current one. Must not be | ||
* a MemoryStream. | ||
*/ | ||
Stream.prototype.imitate = function (other) { | ||
if (other instanceof MemoryStream) { | ||
throw new Error('A MemoryStream was given to imitate(), but it only ' + | ||
'supports a Stream. Read more about this restriction here: ' + | ||
'https://github.com/staltz/xstream#faq'); | ||
} | ||
other._setHIL(this); | ||
}; | ||
/** | ||
* Forces the Stream to emit the given value to its listeners. | ||
@@ -1539,11 +1589,10 @@ * | ||
/** | ||
* Combines multiple streams together to return a stream whose events are | ||
* calculated from the latest events of each of the input streams. | ||
* Combines multiple input streams together to return a stream whose events | ||
* are arrays that collect the latest events from each input stream. | ||
* | ||
* *combine* remembers the most recent event from each of the input streams. | ||
* When any of the input streams emits an event, that event together with all | ||
* the other saved events are combined in the `project` function which should | ||
* return a value. That value will be emitted on the output stream. It's | ||
* essentially a way of mixing the events from multiple streams according to a | ||
* formula. | ||
* *combine* internally remembers the most recent event from each of the input | ||
* streams. When any of the input streams emits an event, that event together | ||
* with all the other saved events are combined into an array. That array will | ||
* be emitted on the output stream. It's essentially a way of joining together | ||
* the events from multiple streams. | ||
* | ||
@@ -1555,3 +1604,3 @@ * Marble diagram: | ||
* ----a-----b-----c--d------ | ||
* combine((x,y) => x+y) | ||
* combine | ||
* ----1a-2a-2b-3b-3c-3d-4d-- | ||
@@ -1561,18 +1610,13 @@ * ``` | ||
* @factory true | ||
* @param {Function} project A function of type `(x: T1, y: T2) => R` or | ||
* similar that takes the most recent events `x` and `y` from the input | ||
* streams and returns a value. The output stream will emit that value. The | ||
* number of arguments for this function should match the number of input | ||
* streams. | ||
* @param {Stream} stream1 A stream to combine together with other streams. | ||
* @param {Stream} stream2 A stream to combine together with other streams. | ||
* Two or more streams may be given as arguments. | ||
* Multiple streams, not just two, may be given as arguments. | ||
* @return {Stream} | ||
*/ | ||
Stream.combine = function combine(project) { | ||
Stream.combine = function combine() { | ||
var streams = []; | ||
for (var _i = 1; _i < arguments.length; _i++) { | ||
streams[_i - 1] = arguments[_i]; | ||
for (var _i = 0; _i < arguments.length; _i++) { | ||
streams[_i - 0] = arguments[_i]; | ||
} | ||
return new Stream(new CombineProducer(project, streams)); | ||
return new Stream(new CombineProducer(streams)); | ||
}; | ||
@@ -1582,99 +1626,2 @@ return Stream; | ||
exports.Stream = Stream; | ||
var MimicStream = (function (_super) { | ||
__extends(MimicStream, _super); | ||
function MimicStream() { | ||
_super.call(this); | ||
} | ||
MimicStream.prototype._add = function (il) { | ||
var t = this._target; | ||
if (!t) | ||
return; | ||
t._add(il); | ||
}; | ||
MimicStream.prototype._remove = function (il) { | ||
var t = this._target; | ||
if (!t) | ||
return; | ||
t._remove(il); | ||
}; | ||
/** | ||
* This method exists only on a MimicStream, which is created through | ||
* `xs.createMimic()`. *imitate* changes this current MimicStream to behave | ||
* like the `other` given stream. | ||
* | ||
* The `imitate` method and the `MimicStream` type exist to allow one thing: | ||
* **circular dependency of streams**. For instance, let's imagine that for | ||
* some reason you need to create a circular dependency where stream `first$` | ||
* depends on stream `second$` which in turn depends on `first$`: | ||
* | ||
* <!-- skip-example --> | ||
* ```js | ||
* import delay from 'xstream/extra/delay' | ||
* | ||
* var first$ = second$.map(x => x * 10).take(3); | ||
* var second$ = first$.map(x => x + 1).startWith(1).compose(delay(100)); | ||
* ``` | ||
* | ||
* However, that is invalid JavaScript, because `second$` is undefined | ||
* on the first line. This is how a MimicStream and imitate can help solve it: | ||
* | ||
* ```js | ||
* import delay from 'xstream/extra/delay' | ||
* | ||
* var secondMimic$ = xs.createMimic(); | ||
* var first$ = secondMimic$.map(x => x * 10).take(3); | ||
* var second$ = first$.map(x => x + 1).startWith(1).compose(delay(100)); | ||
* secondMimic$.imitate(second$); | ||
* ``` | ||
* | ||
* We create `secondMimic$` before the others, so it can be used in the | ||
* declaration of `first$`. Then, after both `first$` and `second$` are | ||
* defined, we hook `secondMimic$` with `second$` with `imitate()` to tell | ||
* that they are "the same". `imitate` will not trigger the start of any | ||
* stream, it simply forwards listeners of `secondMimic$` to `second$`. | ||
* | ||
* The following is an example where `imitate()` is important in Cycle.js | ||
* applications. A parent component contains some child components. A child | ||
* has an action stream which is given to the parent to define its state: | ||
* | ||
* <!-- skip-example --> | ||
* ```js | ||
* const childActionMimic$ = xs.createMimic(); | ||
* const parent = Parent({...sources, childAction$: childActionMimic$}); | ||
* const childAction$ = parent.state$.map(s => s.child.action$).flatten(); | ||
* childActionMimic$.imitate(childAction$); | ||
* ``` | ||
* | ||
* The *imitate* method returns nothing. Instead, it changes the behavior of | ||
* the current stream, making it re-emit whatever events are emitted by the | ||
* given `other` stream. | ||
* | ||
* Note, though, that **`imitate()` does not support MemoryStreams**. 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. It's useful to think about | ||
* MemoryStreams as cells in a spreadsheet. It doesn't make any sense to | ||
* define a spreadsheet cell `A1` with a formula that depends on `B1` and | ||
* cell `B1` defined with a formula that depends on `A1`. | ||
* | ||
* If 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. | ||
* | ||
* @param {Stream} other The stream to imitate on the current one. Must not be | ||
* a MemoryStream. | ||
*/ | ||
MimicStream.prototype.imitate = function (other) { | ||
if (other instanceof MemoryStream) { | ||
throw new Error('A MemoryStream was given to imitate(), but it only ' + | ||
'supports a Stream. Read more about this restriction here: ' + | ||
'https://github.com/staltz/xstream#faq'); | ||
} | ||
this._target = other; | ||
}; | ||
return MimicStream; | ||
}(Stream)); | ||
exports.MimicStream = MimicStream; | ||
var MemoryStream = (function (_super) { | ||
@@ -1681,0 +1628,0 @@ __extends(MemoryStream, _super); |
@@ -34,13 +34,2 @@ (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.xstream = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ | ||
} | ||
function invoke(f, args) { | ||
switch (args.length) { | ||
case 0: return f(); | ||
case 1: return f(args[0]); | ||
case 2: return f(args[0], args[1]); | ||
case 3: return f(args[0], args[1], args[2]); | ||
case 4: return f(args[0], args[1], args[2], args[3]); | ||
case 5: return f(args[0], args[1], args[2], args[3], args[4]); | ||
default: return f.apply(void 0, args); | ||
} | ||
} | ||
function compose2(f1, f2) { | ||
@@ -56,2 +45,49 @@ return function composedFn(arg) { | ||
} | ||
var MergeProducer = (function () { | ||
function MergeProducer(streams) { | ||
this.streams = streams; | ||
this.type = 'merge'; | ||
this.out = exports.emptyListener; | ||
this.ac = streams.length; | ||
} | ||
MergeProducer.prototype._start = function (out) { | ||
this.out = out; | ||
var s = this.streams; | ||
var L = s.length; | ||
for (var i = 0; i < L; i++) { | ||
s[i]._add(this); | ||
} | ||
}; | ||
MergeProducer.prototype._stop = function () { | ||
var s = this.streams; | ||
var L = s.length; | ||
for (var i = 0; i < L; i++) { | ||
s[i]._remove(this); | ||
} | ||
this.out = null; | ||
this.ac = L; | ||
}; | ||
MergeProducer.prototype._n = function (t) { | ||
var u = this.out; | ||
if (!u) | ||
return; | ||
u._n(t); | ||
}; | ||
MergeProducer.prototype._e = function (err) { | ||
var u = this.out; | ||
if (!u) | ||
return; | ||
u._e(err); | ||
}; | ||
MergeProducer.prototype._c = function () { | ||
if (--this.ac === 0) { | ||
var u = this.out; | ||
if (!u) | ||
return; | ||
u._c(); | ||
} | ||
}; | ||
return MergeProducer; | ||
}()); | ||
exports.MergeProducer = MergeProducer; | ||
var CombineListener = (function () { | ||
@@ -68,8 +104,3 @@ function CombineListener(i, p) { | ||
if (p.up(t, this.i)) { | ||
try { | ||
out._n(invoke(p.project, p.vals)); | ||
} | ||
catch (e) { | ||
out._e(e); | ||
} | ||
out._n(p.vals); | ||
} | ||
@@ -95,4 +126,3 @@ }; | ||
var CombineProducer = (function () { | ||
function CombineProducer(project, streams) { | ||
this.project = project; | ||
function CombineProducer(streams) { | ||
this.streams = streams; | ||
@@ -118,4 +148,6 @@ this.type = 'combine'; | ||
var n = s.length; | ||
if (n === 0) | ||
this.zero(out); | ||
if (n === 0) { | ||
out._n(this.vals); | ||
out._c(); | ||
} | ||
else { | ||
@@ -138,11 +170,2 @@ for (var i = 0; i < n; i++) { | ||
}; | ||
CombineProducer.prototype.zero = function (out) { | ||
try { | ||
out._n(this.project()); | ||
out._c(); | ||
} | ||
catch (e) { | ||
out._e(e); | ||
} | ||
}; | ||
return CombineProducer; | ||
@@ -194,49 +217,2 @@ }()); | ||
exports.FromPromiseProducer = FromPromiseProducer; | ||
var MergeProducer = (function () { | ||
function MergeProducer(streams) { | ||
this.streams = streams; | ||
this.type = 'merge'; | ||
this.out = exports.emptyListener; | ||
this.ac = streams.length; | ||
} | ||
MergeProducer.prototype._start = function (out) { | ||
this.out = out; | ||
var s = this.streams; | ||
var L = s.length; | ||
for (var i = 0; i < L; i++) { | ||
s[i]._add(this); | ||
} | ||
}; | ||
MergeProducer.prototype._stop = function () { | ||
var s = this.streams; | ||
var L = s.length; | ||
for (var i = 0; i < L; i++) { | ||
s[i]._remove(this); | ||
} | ||
this.out = null; | ||
this.ac = L; | ||
}; | ||
MergeProducer.prototype._n = function (t) { | ||
var u = this.out; | ||
if (!u) | ||
return; | ||
u._n(t); | ||
}; | ||
MergeProducer.prototype._e = function (err) { | ||
var u = this.out; | ||
if (!u) | ||
return; | ||
u._e(err); | ||
}; | ||
MergeProducer.prototype._c = function () { | ||
if (--this.ac === 0) { | ||
var u = this.out; | ||
if (!u) | ||
return; | ||
u._c(); | ||
} | ||
}; | ||
return MergeProducer; | ||
}()); | ||
exports.MergeProducer = MergeProducer; | ||
var PeriodicProducer = (function () { | ||
@@ -834,3 +810,2 @@ function PeriodicProducer(period) { | ||
u._c(); | ||
this._stop(); | ||
} | ||
@@ -858,2 +833,3 @@ }; | ||
this._ils = []; | ||
this._hil = null; | ||
} | ||
@@ -870,2 +846,5 @@ Stream.prototype._n = function (t) { | ||
} | ||
var h = this._hil; | ||
if (h) | ||
h._n(t); | ||
}; | ||
@@ -882,2 +861,5 @@ Stream.prototype._e = function (err) { | ||
} | ||
var h = this._hil; | ||
if (h) | ||
h._e(err); | ||
this._x(); | ||
@@ -895,2 +877,5 @@ }; | ||
} | ||
var h = this._hil; | ||
if (h) | ||
h._c(); | ||
this._x(); | ||
@@ -946,2 +931,5 @@ }; | ||
}; | ||
Stream.prototype._setHIL = function (il) { | ||
this._hil = il; | ||
}; | ||
Stream.prototype.ctor = function () { | ||
@@ -969,6 +957,2 @@ return this instanceof MemoryStream ? MemoryStream : Stream; | ||
Stream.createMimic = function () { | ||
return new MimicStream(); | ||
}; | ||
Stream.never = function () { | ||
@@ -1112,2 +1096,11 @@ return new Stream({ _start: noop, _stop: noop }); | ||
Stream.prototype.imitate = function (other) { | ||
if (other instanceof MemoryStream) { | ||
throw new Error('A MemoryStream was given to imitate(), but it only ' + | ||
'supports a Stream. Read more about this restriction here: ' + | ||
'https://github.com/staltz/xstream#faq'); | ||
} | ||
other._setHIL(this); | ||
}; | ||
Stream.prototype.shamefullySendNext = function (value) { | ||
@@ -1125,8 +1118,8 @@ this._n(value); | ||
Stream.combine = function combine(project) { | ||
Stream.combine = function combine() { | ||
var streams = []; | ||
for (var _i = 1; _i < arguments.length; _i++) { | ||
streams[_i - 1] = arguments[_i]; | ||
for (var _i = 0; _i < arguments.length; _i++) { | ||
streams[_i - 0] = arguments[_i]; | ||
} | ||
return new Stream(new CombineProducer(project, streams)); | ||
return new Stream(new CombineProducer(streams)); | ||
}; | ||
@@ -1136,31 +1129,2 @@ return Stream; | ||
exports.Stream = Stream; | ||
var MimicStream = (function (_super) { | ||
__extends(MimicStream, _super); | ||
function MimicStream() { | ||
_super.call(this); | ||
} | ||
MimicStream.prototype._add = function (il) { | ||
var t = this._target; | ||
if (!t) | ||
return; | ||
t._add(il); | ||
}; | ||
MimicStream.prototype._remove = function (il) { | ||
var t = this._target; | ||
if (!t) | ||
return; | ||
t._remove(il); | ||
}; | ||
MimicStream.prototype.imitate = function (other) { | ||
if (other instanceof MemoryStream) { | ||
throw new Error('A MemoryStream was given to imitate(), but it only ' + | ||
'supports a Stream. Read more about this restriction here: ' + | ||
'https://github.com/staltz/xstream#faq'); | ||
} | ||
this._target = other; | ||
}; | ||
return MimicStream; | ||
}(Stream)); | ||
exports.MimicStream = MimicStream; | ||
var MemoryStream = (function (_super) { | ||
@@ -1216,3 +1180,2 @@ __extends(MemoryStream, _super); | ||
exports.MemoryStream = core_1.MemoryStream; | ||
exports.MimicStream = core_1.MimicStream; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -1219,0 +1182,0 @@ exports.default = core_1.Stream; |
@@ -1,1 +0,1 @@ | ||
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.xstream=f()}})(function(){var define,module,exports;return function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}({1:[function(require,module,exports){"use strict";var __extends=this&&this.__extends||function(d,b){for(var p in b)if(b.hasOwnProperty(p))d[p]=b[p];function __(){this.constructor=d}d.prototype=b===null?Object.create(b):(__.prototype=b.prototype,new __)};var empty={};function noop(){}function copy(a){var l=a.length;var b=Array(l);for(var i=0;i<l;++i){b[i]=a[i]}return b}exports.emptyListener={_n:noop,_e:noop,_c:noop};function internalizeProducer(producer){producer._start=function _start(il){il.next=il._n;il.error=il._e;il.complete=il._c;this.start(il)};producer._stop=producer.stop}function invoke(f,args){switch(args.length){case 0:return f();case 1:return f(args[0]);case 2:return f(args[0],args[1]);case 3:return f(args[0],args[1],args[2]);case 4:return f(args[0],args[1],args[2],args[3]);case 5:return f(args[0],args[1],args[2],args[3],args[4]);default:return f.apply(void 0,args)}}function compose2(f1,f2){return function composedFn(arg){return f1(f2(arg))}}function and(f1,f2){return function andFn(t){return f1(t)&&f2(t)}}var CombineListener=function(){function CombineListener(i,p){this.i=i;this.p=p;p.ils.push(this)}CombineListener.prototype._n=function(t){var p=this.p,out=p.out;if(!out)return;if(p.up(t,this.i)){try{out._n(invoke(p.project,p.vals))}catch(e){out._e(e)}}};CombineListener.prototype._e=function(err){var out=this.p.out;if(!out)return;out._e(err)};CombineListener.prototype._c=function(){var p=this.p;if(!p.out)return;if(--p.ac===0){p.out._c()}};return CombineListener}();exports.CombineListener=CombineListener;var CombineProducer=function(){function CombineProducer(project,streams){this.project=project;this.streams=streams;this.type="combine";this.out=exports.emptyListener;this.ils=[];var n=this.ac=this.left=streams.length;var vals=this.vals=new Array(n);for(var i=0;i<n;i++){vals[i]=empty}}CombineProducer.prototype.up=function(t,i){var v=this.vals[i];var left=!this.left?0:v===empty?--this.left:this.left;this.vals[i]=t;return left===0};CombineProducer.prototype._start=function(out){this.out=out;var s=this.streams;var n=s.length;if(n===0)this.zero(out);else{for(var i=0;i<n;i++){s[i]._add(new CombineListener(i,this))}}};CombineProducer.prototype._stop=function(){var s=this.streams;var n=this.ac=this.left=s.length;var vals=this.vals=new Array(n);for(var i=0;i<n;i++){s[i]._remove(this.ils[i]);vals[i]=empty}this.out=null;this.ils=[]};CombineProducer.prototype.zero=function(out){try{out._n(this.project());out._c()}catch(e){out._e(e)}};return CombineProducer}();exports.CombineProducer=CombineProducer;var FromArrayProducer=function(){function FromArrayProducer(a){this.a=a;this.type="fromArray"}FromArrayProducer.prototype._start=function(out){var a=this.a;for(var i=0,l=a.length;i<l;i++){out._n(a[i])}out._c()};FromArrayProducer.prototype._stop=function(){};return FromArrayProducer}();exports.FromArrayProducer=FromArrayProducer;var FromPromiseProducer=function(){function FromPromiseProducer(p){this.p=p;this.type="fromPromise";this.on=false}FromPromiseProducer.prototype._start=function(out){var prod=this;this.on=true;this.p.then(function(v){if(prod.on){out._n(v);out._c()}},function(e){out._e(e)}).then(null,function(err){setTimeout(function(){throw err})})};FromPromiseProducer.prototype._stop=function(){this.on=false};return FromPromiseProducer}();exports.FromPromiseProducer=FromPromiseProducer;var MergeProducer=function(){function MergeProducer(streams){this.streams=streams;this.type="merge";this.out=exports.emptyListener;this.ac=streams.length}MergeProducer.prototype._start=function(out){this.out=out;var s=this.streams;var L=s.length;for(var i=0;i<L;i++){s[i]._add(this)}};MergeProducer.prototype._stop=function(){var s=this.streams;var L=s.length;for(var i=0;i<L;i++){s[i]._remove(this)}this.out=null;this.ac=L};MergeProducer.prototype._n=function(t){var u=this.out;if(!u)return;u._n(t)};MergeProducer.prototype._e=function(err){var u=this.out;if(!u)return;u._e(err)};MergeProducer.prototype._c=function(){if(--this.ac===0){var u=this.out;if(!u)return;u._c()}};return MergeProducer}();exports.MergeProducer=MergeProducer;var PeriodicProducer=function(){function PeriodicProducer(period){this.period=period;this.type="periodic";this.intervalID=-1;this.i=0}PeriodicProducer.prototype._start=function(stream){var self=this;function intervalHandler(){stream._n(self.i++)}this.intervalID=setInterval(intervalHandler,this.period)};PeriodicProducer.prototype._stop=function(){if(this.intervalID!==-1)clearInterval(this.intervalID);this.intervalID=-1;this.i=0};return PeriodicProducer}();exports.PeriodicProducer=PeriodicProducer;var DebugOperator=function(){function DebugOperator(arg,ins){this.ins=ins;this.type="debug";this.out=null;this.s=null;this.l=null;if(typeof arg==="string"){this.l=arg}else{this.s=arg}}DebugOperator.prototype._start=function(out){this.out=out;this.ins._add(this)};DebugOperator.prototype._stop=function(){this.ins._remove(this);this.out=null};DebugOperator.prototype._n=function(t){var u=this.out;if(!u)return;var s=this.s,l=this.l;if(s){try{s(t)}catch(e){u._e(e)}}else if(l){console.log(l+":",t)}else{console.log(t)}u._n(t)};DebugOperator.prototype._e=function(err){var u=this.out;if(!u)return;u._e(err)};DebugOperator.prototype._c=function(){var u=this.out;if(!u)return;u._c()};return DebugOperator}();exports.DebugOperator=DebugOperator;var DropOperator=function(){function DropOperator(max,ins){this.max=max;this.ins=ins;this.type="drop";this.out=null;this.dropped=0}DropOperator.prototype._start=function(out){this.out=out;this.ins._add(this)};DropOperator.prototype._stop=function(){this.ins._remove(this);this.out=null;this.dropped=0};DropOperator.prototype._n=function(t){var u=this.out;if(!u)return;if(this.dropped++>=this.max)u._n(t)};DropOperator.prototype._e=function(err){var u=this.out;if(!u)return;u._e(err)};DropOperator.prototype._c=function(){var u=this.out;if(!u)return;u._c()};return DropOperator}();exports.DropOperator=DropOperator;var OtherIL=function(){function OtherIL(out,op){this.out=out;this.op=op}OtherIL.prototype._n=function(t){this.op.end()};OtherIL.prototype._e=function(err){this.out._e(err)};OtherIL.prototype._c=function(){this.op.end()};return OtherIL}();var EndWhenOperator=function(){function EndWhenOperator(o,ins){this.o=o;this.ins=ins;this.type="endWhen";this.out=null;this.oil=exports.emptyListener}EndWhenOperator.prototype._start=function(out){this.out=out;this.o._add(this.oil=new OtherIL(out,this));this.ins._add(this)};EndWhenOperator.prototype._stop=function(){this.ins._remove(this);this.o._remove(this.oil);this.out=null;this.oil=null};EndWhenOperator.prototype.end=function(){var u=this.out;if(!u)return;u._c()};EndWhenOperator.prototype._n=function(t){var u=this.out;if(!u)return;u._n(t)};EndWhenOperator.prototype._e=function(err){var u=this.out;if(!u)return;u._e(err)};EndWhenOperator.prototype._c=function(){this.end()};return EndWhenOperator}();exports.EndWhenOperator=EndWhenOperator;var FilterOperator=function(){function FilterOperator(passes,ins){this.passes=passes;this.ins=ins;this.type="filter";this.out=null}FilterOperator.prototype._start=function(out){this.out=out;this.ins._add(this)};FilterOperator.prototype._stop=function(){this.ins._remove(this);this.out=null};FilterOperator.prototype._n=function(t){var u=this.out;if(!u)return;try{if(this.passes(t))u._n(t)}catch(e){u._e(e)}};FilterOperator.prototype._e=function(err){var u=this.out;if(!u)return;u._e(err)};FilterOperator.prototype._c=function(){var u=this.out;if(!u)return;u._c()};return FilterOperator}();exports.FilterOperator=FilterOperator;var FlattenListener=function(){function FlattenListener(out,op){this.out=out;this.op=op}FlattenListener.prototype._n=function(t){this.out._n(t)};FlattenListener.prototype._e=function(err){this.out._e(err)};FlattenListener.prototype._c=function(){this.op.inner=null;this.op.less()};return FlattenListener}();var FlattenOperator=function(){function FlattenOperator(ins){this.ins=ins;this.type="flatten";this.inner=null;this.il=null;this.open=true;this.out=null}FlattenOperator.prototype._start=function(out){this.out=out;this.ins._add(this)};FlattenOperator.prototype._stop=function(){this.ins._remove(this);this.inner=null;this.il=null;this.open=true;this.out=null};FlattenOperator.prototype.less=function(){var u=this.out;if(!u)return;if(!this.open&&!this.inner)u._c()};FlattenOperator.prototype._n=function(s){var u=this.out;if(!u)return;var _a=this,inner=_a.inner,il=_a.il;if(inner&&il)inner._remove(il);(this.inner=s)._add(this.il=new FlattenListener(u,this))};FlattenOperator.prototype._e=function(err){var u=this.out;if(!u)return;u._e(err)};FlattenOperator.prototype._c=function(){this.open=false;this.less()};return FlattenOperator}();exports.FlattenOperator=FlattenOperator;var FoldOperator=function(){function FoldOperator(f,seed,ins){this.f=f;this.seed=seed;this.ins=ins;this.type="fold";this.out=null;this.acc=seed}FoldOperator.prototype._start=function(out){this.out=out;out._n(this.acc);this.ins._add(this)};FoldOperator.prototype._stop=function(){this.ins._remove(this);this.out=null;this.acc=this.seed};FoldOperator.prototype._n=function(t){var u=this.out;if(!u)return;try{u._n(this.acc=this.f(this.acc,t))}catch(e){u._e(e)}};FoldOperator.prototype._e=function(err){var u=this.out;if(!u)return;u._e(err)};FoldOperator.prototype._c=function(){var u=this.out;if(!u)return;u._c()};return FoldOperator}();exports.FoldOperator=FoldOperator;var LastOperator=function(){function LastOperator(ins){this.ins=ins;this.type="last";this.out=null;this.has=false;this.val=empty}LastOperator.prototype._start=function(out){this.out=out;this.ins._add(this)};LastOperator.prototype._stop=function(){this.ins._remove(this);this.out=null;this.has=false;this.val=empty};LastOperator.prototype._n=function(t){this.has=true;this.val=t};LastOperator.prototype._e=function(err){var u=this.out;if(!u)return;u._e(err)};LastOperator.prototype._c=function(){var u=this.out;if(!u)return;if(this.has){u._n(this.val);u._c()}else{u._e("TODO show proper error")}};return LastOperator}();exports.LastOperator=LastOperator;var MapFlattenInner=function(){function MapFlattenInner(out,op){this.out=out;this.op=op}MapFlattenInner.prototype._n=function(r){this.out._n(r)};MapFlattenInner.prototype._e=function(err){this.out._e(err)};MapFlattenInner.prototype._c=function(){this.op.inner=null;this.op.less()};return MapFlattenInner}();var MapFlattenOperator=function(){function MapFlattenOperator(mapOp){this.mapOp=mapOp;this.inner=null;this.il=null;this.open=true;this.out=null;this.type=mapOp.type+"+flatten";this.ins=mapOp.ins}MapFlattenOperator.prototype._start=function(out){this.out=out;this.mapOp.ins._add(this)};MapFlattenOperator.prototype._stop=function(){this.mapOp.ins._remove(this);this.inner=null;this.il=null;this.open=true;this.out=null};MapFlattenOperator.prototype.less=function(){if(!this.open&&!this.inner){var u=this.out;if(!u)return;u._c()}};MapFlattenOperator.prototype._n=function(v){var u=this.out;if(!u)return;var _a=this,inner=_a.inner,il=_a.il;if(inner&&il)inner._remove(il);try{(this.inner=this.mapOp.project(v))._add(this.il=new MapFlattenInner(u,this))}catch(e){u._e(e)}};MapFlattenOperator.prototype._e=function(err){var u=this.out;if(!u)return;u._e(err)};MapFlattenOperator.prototype._c=function(){this.open=false;this.less()};return MapFlattenOperator}();exports.MapFlattenOperator=MapFlattenOperator;var MapOperator=function(){function MapOperator(project,ins){this.project=project;this.ins=ins;this.type="map";this.out=null}MapOperator.prototype._start=function(out){this.out=out;this.ins._add(this)};MapOperator.prototype._stop=function(){this.ins._remove(this);this.out=null};MapOperator.prototype._n=function(t){var u=this.out;if(!u)return;try{u._n(this.project(t))}catch(e){u._e(e)}};MapOperator.prototype._e=function(err){var u=this.out;if(!u)return;u._e(err)};MapOperator.prototype._c=function(){var u=this.out;if(!u)return;u._c()};return MapOperator}();exports.MapOperator=MapOperator;var FilterMapOperator=function(_super){__extends(FilterMapOperator,_super);function FilterMapOperator(passes,project,ins){_super.call(this,project,ins);this.passes=passes;this.type="filter+map"}FilterMapOperator.prototype._n=function(v){if(this.passes(v)){_super.prototype._n.call(this,v)}};return FilterMapOperator}(MapOperator);exports.FilterMapOperator=FilterMapOperator;var ReplaceErrorOperator=function(){function ReplaceErrorOperator(fn,ins){this.fn=fn;this.ins=ins;this.type="replaceError";this.out=empty}ReplaceErrorOperator.prototype._start=function(out){this.out=out;this.ins._add(this)};ReplaceErrorOperator.prototype._stop=function(){this.ins._remove(this);this.out=null};ReplaceErrorOperator.prototype._n=function(t){var u=this.out;if(!u)return;u._n(t)};ReplaceErrorOperator.prototype._e=function(err){var u=this.out;if(!u)return;try{this.ins._remove(this);(this.ins=this.fn(err))._add(this)}catch(e){u._e(e)}};ReplaceErrorOperator.prototype._c=function(){var u=this.out;if(!u)return;u._c()};return ReplaceErrorOperator}();exports.ReplaceErrorOperator=ReplaceErrorOperator;var StartWithOperator=function(){function StartWithOperator(ins,value){this.ins=ins;this.value=value;this.type="startWith";this.out=exports.emptyListener}StartWithOperator.prototype._start=function(out){this.out=out;this.out._n(this.value);this.ins._add(out)};StartWithOperator.prototype._stop=function(){this.ins._remove(this.out);this.out=null};return StartWithOperator}();exports.StartWithOperator=StartWithOperator;var TakeOperator=function(){function TakeOperator(max,ins){this.max=max;this.ins=ins;this.type="take";this.out=null;this.taken=0}TakeOperator.prototype._start=function(out){this.out=out;this.ins._add(this)};TakeOperator.prototype._stop=function(){this.ins._remove(this);this.out=null;this.taken=0};TakeOperator.prototype._n=function(t){var u=this.out;if(!u)return;if(this.taken++<this.max-1){u._n(t)}else{u._n(t);u._c();this._stop()}};TakeOperator.prototype._e=function(err){var u=this.out;if(!u)return;u._e(err)};TakeOperator.prototype._c=function(){var u=this.out;if(!u)return;u._c()};return TakeOperator}();exports.TakeOperator=TakeOperator;var Stream=function(){function Stream(producer){this._stopID=empty;this._prod=producer;this._ils=[]}Stream.prototype._n=function(t){var a=this._ils;var L=a.length;if(L==1)a[0]._n(t);else{var b=copy(a);for(var i=0;i<L;i++)b[i]._n(t)}};Stream.prototype._e=function(err){var a=this._ils;var L=a.length;if(L==1)a[0]._e(err);else{var b=copy(a);for(var i=0;i<L;i++)b[i]._e(err)}this._x()};Stream.prototype._c=function(){var a=this._ils;var L=a.length;if(L==1)a[0]._c();else{var b=copy(a);for(var i=0;i<L;i++)b[i]._c()}this._x()};Stream.prototype._x=function(){if(this._ils.length===0)return;if(this._prod)this._prod._stop();this._ils=[]};Stream.prototype.addListener=function(listener){if(typeof listener.next!=="function"||typeof listener.error!=="function"||typeof listener.complete!=="function"){throw new Error("stream.addListener() requires all three next, error, "+"and complete functions.")}listener._n=listener.next;listener._e=listener.error;listener._c=listener.complete;this._add(listener)};Stream.prototype.removeListener=function(listener){this._remove(listener)};Stream.prototype._add=function(il){var a=this._ils;a.push(il);if(a.length===1){if(this._stopID!==empty){clearTimeout(this._stopID);this._stopID=empty}var p=this._prod;if(p)p._start(this)}};Stream.prototype._remove=function(il){var a=this._ils;var i=a.indexOf(il);if(i>-1){a.splice(i,1);var p_1=this._prod;if(p_1&&a.length<=0){this._stopID=setTimeout(function(){return p_1._stop()})}}};Stream.prototype.ctor=function(){return this instanceof MemoryStream?MemoryStream:Stream};Stream.create=function(producer){if(producer){if(typeof producer.start!=="function"||typeof producer.stop!=="function"){throw new Error("producer requires both start and stop functions")}internalizeProducer(producer)}return new Stream(producer)};Stream.createWithMemory=function(producer){if(producer){internalizeProducer(producer)}return new MemoryStream(producer)};Stream.createMimic=function(){return new MimicStream};Stream.never=function(){return new Stream({_start:noop,_stop:noop})};Stream.empty=function(){return new Stream({_start:function(il){il._c()},_stop:noop})};Stream.throw=function(error){return new Stream({_start:function(il){il._e(error)},_stop:noop})};Stream.of=function(){var items=[];for(var _i=0;_i<arguments.length;_i++){items[_i-0]=arguments[_i]}return Stream.fromArray(items)};Stream.fromArray=function(array){return new Stream(new FromArrayProducer(array))};Stream.fromPromise=function(promise){return new Stream(new FromPromiseProducer(promise))};Stream.periodic=function(period){return new Stream(new PeriodicProducer(period))};Stream.merge=function(){var streams=[];for(var _i=0;_i<arguments.length;_i++){streams[_i-0]=arguments[_i]}return new Stream(new MergeProducer(streams))};Stream.prototype._map=function(project){var p=this._prod;var ctor=this.ctor();if(p instanceof FilterOperator){return new ctor(new FilterMapOperator(p.passes,project,p.ins))}if(p instanceof FilterMapOperator){return new ctor(new FilterMapOperator(p.passes,compose2(project,p.project),p.ins))}if(p instanceof MapOperator){return new ctor(new MapOperator(compose2(project,p.project),p.ins))}return new ctor(new MapOperator(project,this))};Stream.prototype.map=function(project){return this._map(project)};Stream.prototype.mapTo=function(projectedValue){var s=this.map(function(){return projectedValue});var op=s._prod;op.type=op.type.replace("map","mapTo");return s};Stream.prototype.filter=function(passes){var p=this._prod;if(p instanceof FilterOperator){return new Stream(new FilterOperator(and(passes,p.passes),p.ins))}return new Stream(new FilterOperator(passes,this))};Stream.prototype.take=function(amount){return new(this.ctor())(new TakeOperator(amount,this))};Stream.prototype.drop=function(amount){return new Stream(new DropOperator(amount,this))};Stream.prototype.last=function(){return new Stream(new LastOperator(this))};Stream.prototype.startWith=function(initial){return new MemoryStream(new StartWithOperator(this,initial))};Stream.prototype.endWhen=function(other){return new(this.ctor())(new EndWhenOperator(other,this))};Stream.prototype.fold=function(accumulate,seed){return new MemoryStream(new FoldOperator(accumulate,seed,this))};Stream.prototype.replaceError=function(replace){return new(this.ctor())(new ReplaceErrorOperator(replace,this))};Stream.prototype.flatten=function(){var p=this._prod;return new Stream(p instanceof MapOperator&&!(p instanceof FilterMapOperator)?new MapFlattenOperator(p):new FlattenOperator(this))};Stream.prototype.compose=function(operator){return operator(this)};Stream.prototype.remember=function(){var _this=this;return new MemoryStream({_start:function(il){var p=_this._prod;if(p)p._start(il)},_stop:function(){var p=_this._prod;if(p)p._stop()}})};Stream.prototype.debug=function(labelOrSpy){return new(this.ctor())(new DebugOperator(labelOrSpy,this))};Stream.prototype.shamefullySendNext=function(value){this._n(value)};Stream.prototype.shamefullySendError=function(error){this._e(error)};Stream.prototype.shamefullySendComplete=function(){this._c()};Stream.combine=function combine(project){var streams=[];for(var _i=1;_i<arguments.length;_i++){streams[_i-1]=arguments[_i]}return new Stream(new CombineProducer(project,streams))};return Stream}();exports.Stream=Stream;var MimicStream=function(_super){__extends(MimicStream,_super);function MimicStream(){_super.call(this)}MimicStream.prototype._add=function(il){var t=this._target;if(!t)return;t._add(il)};MimicStream.prototype._remove=function(il){var t=this._target;if(!t)return;t._remove(il)};MimicStream.prototype.imitate=function(other){if(other instanceof MemoryStream){throw new Error("A MemoryStream was given to imitate(), but it only "+"supports a Stream. Read more about this restriction here: "+"https://github.com/staltz/xstream#faq")}this._target=other};return MimicStream}(Stream);exports.MimicStream=MimicStream;var MemoryStream=function(_super){__extends(MemoryStream,_super);function MemoryStream(producer){_super.call(this,producer);this._has=false}MemoryStream.prototype._n=function(x){this._v=x;this._has=true;_super.prototype._n.call(this,x)};MemoryStream.prototype._add=function(il){if(this._has){il._n(this._v)}_super.prototype._add.call(this,il)};MemoryStream.prototype._x=function(){this._has=false;_super.prototype._x.call(this)};MemoryStream.prototype.map=function(project){return this._map(project)};MemoryStream.prototype.mapTo=function(projectedValue){return _super.prototype.mapTo.call(this,projectedValue)};MemoryStream.prototype.take=function(amount){return _super.prototype.take.call(this,amount)};MemoryStream.prototype.endWhen=function(other){return _super.prototype.endWhen.call(this,other)};MemoryStream.prototype.replaceError=function(replace){return _super.prototype.replaceError.call(this,replace)};MemoryStream.prototype.debug=function(labelOrSpy){return _super.prototype.debug.call(this,labelOrSpy)};return MemoryStream}(Stream);exports.MemoryStream=MemoryStream;Object.defineProperty(exports,"__esModule",{value:true});exports.default=Stream},{}],2:[function(require,module,exports){"use strict";var core_1=require("./core");exports.Stream=core_1.Stream;exports.MemoryStream=core_1.MemoryStream;exports.MimicStream=core_1.MimicStream;Object.defineProperty(exports,"__esModule",{value:true});exports.default=core_1.Stream},{"./core":1}]},{},[2])(2)}); | ||
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.xstream=f()}})(function(){var define,module,exports;return function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}({1:[function(require,module,exports){"use strict";var __extends=this&&this.__extends||function(d,b){for(var p in b)if(b.hasOwnProperty(p))d[p]=b[p];function __(){this.constructor=d}d.prototype=b===null?Object.create(b):(__.prototype=b.prototype,new __)};var empty={};function noop(){}function copy(a){var l=a.length;var b=Array(l);for(var i=0;i<l;++i){b[i]=a[i]}return b}exports.emptyListener={_n:noop,_e:noop,_c:noop};function internalizeProducer(producer){producer._start=function _start(il){il.next=il._n;il.error=il._e;il.complete=il._c;this.start(il)};producer._stop=producer.stop}function compose2(f1,f2){return function composedFn(arg){return f1(f2(arg))}}function and(f1,f2){return function andFn(t){return f1(t)&&f2(t)}}var MergeProducer=function(){function MergeProducer(streams){this.streams=streams;this.type="merge";this.out=exports.emptyListener;this.ac=streams.length}MergeProducer.prototype._start=function(out){this.out=out;var s=this.streams;var L=s.length;for(var i=0;i<L;i++){s[i]._add(this)}};MergeProducer.prototype._stop=function(){var s=this.streams;var L=s.length;for(var i=0;i<L;i++){s[i]._remove(this)}this.out=null;this.ac=L};MergeProducer.prototype._n=function(t){var u=this.out;if(!u)return;u._n(t)};MergeProducer.prototype._e=function(err){var u=this.out;if(!u)return;u._e(err)};MergeProducer.prototype._c=function(){if(--this.ac===0){var u=this.out;if(!u)return;u._c()}};return MergeProducer}();exports.MergeProducer=MergeProducer;var CombineListener=function(){function CombineListener(i,p){this.i=i;this.p=p;p.ils.push(this)}CombineListener.prototype._n=function(t){var p=this.p,out=p.out;if(!out)return;if(p.up(t,this.i)){out._n(p.vals)}};CombineListener.prototype._e=function(err){var out=this.p.out;if(!out)return;out._e(err)};CombineListener.prototype._c=function(){var p=this.p;if(!p.out)return;if(--p.ac===0){p.out._c()}};return CombineListener}();exports.CombineListener=CombineListener;var CombineProducer=function(){function CombineProducer(streams){this.streams=streams;this.type="combine";this.out=exports.emptyListener;this.ils=[];var n=this.ac=this.left=streams.length;var vals=this.vals=new Array(n);for(var i=0;i<n;i++){vals[i]=empty}}CombineProducer.prototype.up=function(t,i){var v=this.vals[i];var left=!this.left?0:v===empty?--this.left:this.left;this.vals[i]=t;return left===0};CombineProducer.prototype._start=function(out){this.out=out;var s=this.streams;var n=s.length;if(n===0){out._n(this.vals);out._c()}else{for(var i=0;i<n;i++){s[i]._add(new CombineListener(i,this))}}};CombineProducer.prototype._stop=function(){var s=this.streams;var n=this.ac=this.left=s.length;var vals=this.vals=new Array(n);for(var i=0;i<n;i++){s[i]._remove(this.ils[i]);vals[i]=empty}this.out=null;this.ils=[]};return CombineProducer}();exports.CombineProducer=CombineProducer;var FromArrayProducer=function(){function FromArrayProducer(a){this.a=a;this.type="fromArray"}FromArrayProducer.prototype._start=function(out){var a=this.a;for(var i=0,l=a.length;i<l;i++){out._n(a[i])}out._c()};FromArrayProducer.prototype._stop=function(){};return FromArrayProducer}();exports.FromArrayProducer=FromArrayProducer;var FromPromiseProducer=function(){function FromPromiseProducer(p){this.p=p;this.type="fromPromise";this.on=false}FromPromiseProducer.prototype._start=function(out){var prod=this;this.on=true;this.p.then(function(v){if(prod.on){out._n(v);out._c()}},function(e){out._e(e)}).then(null,function(err){setTimeout(function(){throw err})})};FromPromiseProducer.prototype._stop=function(){this.on=false};return FromPromiseProducer}();exports.FromPromiseProducer=FromPromiseProducer;var PeriodicProducer=function(){function PeriodicProducer(period){this.period=period;this.type="periodic";this.intervalID=-1;this.i=0}PeriodicProducer.prototype._start=function(stream){var self=this;function intervalHandler(){stream._n(self.i++)}this.intervalID=setInterval(intervalHandler,this.period)};PeriodicProducer.prototype._stop=function(){if(this.intervalID!==-1)clearInterval(this.intervalID);this.intervalID=-1;this.i=0};return PeriodicProducer}();exports.PeriodicProducer=PeriodicProducer;var DebugOperator=function(){function DebugOperator(arg,ins){this.ins=ins;this.type="debug";this.out=null;this.s=null;this.l=null;if(typeof arg==="string"){this.l=arg}else{this.s=arg}}DebugOperator.prototype._start=function(out){this.out=out;this.ins._add(this)};DebugOperator.prototype._stop=function(){this.ins._remove(this);this.out=null};DebugOperator.prototype._n=function(t){var u=this.out;if(!u)return;var s=this.s,l=this.l;if(s){try{s(t)}catch(e){u._e(e)}}else if(l){console.log(l+":",t)}else{console.log(t)}u._n(t)};DebugOperator.prototype._e=function(err){var u=this.out;if(!u)return;u._e(err)};DebugOperator.prototype._c=function(){var u=this.out;if(!u)return;u._c()};return DebugOperator}();exports.DebugOperator=DebugOperator;var DropOperator=function(){function DropOperator(max,ins){this.max=max;this.ins=ins;this.type="drop";this.out=null;this.dropped=0}DropOperator.prototype._start=function(out){this.out=out;this.ins._add(this)};DropOperator.prototype._stop=function(){this.ins._remove(this);this.out=null;this.dropped=0};DropOperator.prototype._n=function(t){var u=this.out;if(!u)return;if(this.dropped++>=this.max)u._n(t)};DropOperator.prototype._e=function(err){var u=this.out;if(!u)return;u._e(err)};DropOperator.prototype._c=function(){var u=this.out;if(!u)return;u._c()};return DropOperator}();exports.DropOperator=DropOperator;var OtherIL=function(){function OtherIL(out,op){this.out=out;this.op=op}OtherIL.prototype._n=function(t){this.op.end()};OtherIL.prototype._e=function(err){this.out._e(err)};OtherIL.prototype._c=function(){this.op.end()};return OtherIL}();var EndWhenOperator=function(){function EndWhenOperator(o,ins){this.o=o;this.ins=ins;this.type="endWhen";this.out=null;this.oil=exports.emptyListener}EndWhenOperator.prototype._start=function(out){this.out=out;this.o._add(this.oil=new OtherIL(out,this));this.ins._add(this)};EndWhenOperator.prototype._stop=function(){this.ins._remove(this);this.o._remove(this.oil);this.out=null;this.oil=null};EndWhenOperator.prototype.end=function(){var u=this.out;if(!u)return;u._c()};EndWhenOperator.prototype._n=function(t){var u=this.out;if(!u)return;u._n(t)};EndWhenOperator.prototype._e=function(err){var u=this.out;if(!u)return;u._e(err)};EndWhenOperator.prototype._c=function(){this.end()};return EndWhenOperator}();exports.EndWhenOperator=EndWhenOperator;var FilterOperator=function(){function FilterOperator(passes,ins){this.passes=passes;this.ins=ins;this.type="filter";this.out=null}FilterOperator.prototype._start=function(out){this.out=out;this.ins._add(this)};FilterOperator.prototype._stop=function(){this.ins._remove(this);this.out=null};FilterOperator.prototype._n=function(t){var u=this.out;if(!u)return;try{if(this.passes(t))u._n(t)}catch(e){u._e(e)}};FilterOperator.prototype._e=function(err){var u=this.out;if(!u)return;u._e(err)};FilterOperator.prototype._c=function(){var u=this.out;if(!u)return;u._c()};return FilterOperator}();exports.FilterOperator=FilterOperator;var FlattenListener=function(){function FlattenListener(out,op){this.out=out;this.op=op}FlattenListener.prototype._n=function(t){this.out._n(t)};FlattenListener.prototype._e=function(err){this.out._e(err)};FlattenListener.prototype._c=function(){this.op.inner=null;this.op.less()};return FlattenListener}();var FlattenOperator=function(){function FlattenOperator(ins){this.ins=ins;this.type="flatten";this.inner=null;this.il=null;this.open=true;this.out=null}FlattenOperator.prototype._start=function(out){this.out=out;this.ins._add(this)};FlattenOperator.prototype._stop=function(){this.ins._remove(this);this.inner=null;this.il=null;this.open=true;this.out=null};FlattenOperator.prototype.less=function(){var u=this.out;if(!u)return;if(!this.open&&!this.inner)u._c()};FlattenOperator.prototype._n=function(s){var u=this.out;if(!u)return;var _a=this,inner=_a.inner,il=_a.il;if(inner&&il)inner._remove(il);(this.inner=s)._add(this.il=new FlattenListener(u,this))};FlattenOperator.prototype._e=function(err){var u=this.out;if(!u)return;u._e(err)};FlattenOperator.prototype._c=function(){this.open=false;this.less()};return FlattenOperator}();exports.FlattenOperator=FlattenOperator;var FoldOperator=function(){function FoldOperator(f,seed,ins){this.f=f;this.seed=seed;this.ins=ins;this.type="fold";this.out=null;this.acc=seed}FoldOperator.prototype._start=function(out){this.out=out;out._n(this.acc);this.ins._add(this)};FoldOperator.prototype._stop=function(){this.ins._remove(this);this.out=null;this.acc=this.seed};FoldOperator.prototype._n=function(t){var u=this.out;if(!u)return;try{u._n(this.acc=this.f(this.acc,t))}catch(e){u._e(e)}};FoldOperator.prototype._e=function(err){var u=this.out;if(!u)return;u._e(err)};FoldOperator.prototype._c=function(){var u=this.out;if(!u)return;u._c()};return FoldOperator}();exports.FoldOperator=FoldOperator;var LastOperator=function(){function LastOperator(ins){this.ins=ins;this.type="last";this.out=null;this.has=false;this.val=empty}LastOperator.prototype._start=function(out){this.out=out;this.ins._add(this)};LastOperator.prototype._stop=function(){this.ins._remove(this);this.out=null;this.has=false;this.val=empty};LastOperator.prototype._n=function(t){this.has=true;this.val=t};LastOperator.prototype._e=function(err){var u=this.out;if(!u)return;u._e(err)};LastOperator.prototype._c=function(){var u=this.out;if(!u)return;if(this.has){u._n(this.val);u._c()}else{u._e("TODO show proper error")}};return LastOperator}();exports.LastOperator=LastOperator;var MapFlattenInner=function(){function MapFlattenInner(out,op){this.out=out;this.op=op}MapFlattenInner.prototype._n=function(r){this.out._n(r)};MapFlattenInner.prototype._e=function(err){this.out._e(err)};MapFlattenInner.prototype._c=function(){this.op.inner=null;this.op.less()};return MapFlattenInner}();var MapFlattenOperator=function(){function MapFlattenOperator(mapOp){this.mapOp=mapOp;this.inner=null;this.il=null;this.open=true;this.out=null;this.type=mapOp.type+"+flatten";this.ins=mapOp.ins}MapFlattenOperator.prototype._start=function(out){this.out=out;this.mapOp.ins._add(this)};MapFlattenOperator.prototype._stop=function(){this.mapOp.ins._remove(this);this.inner=null;this.il=null;this.open=true;this.out=null};MapFlattenOperator.prototype.less=function(){if(!this.open&&!this.inner){var u=this.out;if(!u)return;u._c()}};MapFlattenOperator.prototype._n=function(v){var u=this.out;if(!u)return;var _a=this,inner=_a.inner,il=_a.il;if(inner&&il)inner._remove(il);try{(this.inner=this.mapOp.project(v))._add(this.il=new MapFlattenInner(u,this))}catch(e){u._e(e)}};MapFlattenOperator.prototype._e=function(err){var u=this.out;if(!u)return;u._e(err)};MapFlattenOperator.prototype._c=function(){this.open=false;this.less()};return MapFlattenOperator}();exports.MapFlattenOperator=MapFlattenOperator;var MapOperator=function(){function MapOperator(project,ins){this.project=project;this.ins=ins;this.type="map";this.out=null}MapOperator.prototype._start=function(out){this.out=out;this.ins._add(this)};MapOperator.prototype._stop=function(){this.ins._remove(this);this.out=null};MapOperator.prototype._n=function(t){var u=this.out;if(!u)return;try{u._n(this.project(t))}catch(e){u._e(e)}};MapOperator.prototype._e=function(err){var u=this.out;if(!u)return;u._e(err)};MapOperator.prototype._c=function(){var u=this.out;if(!u)return;u._c()};return MapOperator}();exports.MapOperator=MapOperator;var FilterMapOperator=function(_super){__extends(FilterMapOperator,_super);function FilterMapOperator(passes,project,ins){_super.call(this,project,ins);this.passes=passes;this.type="filter+map"}FilterMapOperator.prototype._n=function(v){if(this.passes(v)){_super.prototype._n.call(this,v)}};return FilterMapOperator}(MapOperator);exports.FilterMapOperator=FilterMapOperator;var ReplaceErrorOperator=function(){function ReplaceErrorOperator(fn,ins){this.fn=fn;this.ins=ins;this.type="replaceError";this.out=empty}ReplaceErrorOperator.prototype._start=function(out){this.out=out;this.ins._add(this)};ReplaceErrorOperator.prototype._stop=function(){this.ins._remove(this);this.out=null};ReplaceErrorOperator.prototype._n=function(t){var u=this.out;if(!u)return;u._n(t)};ReplaceErrorOperator.prototype._e=function(err){var u=this.out;if(!u)return;try{this.ins._remove(this);(this.ins=this.fn(err))._add(this)}catch(e){u._e(e)}};ReplaceErrorOperator.prototype._c=function(){var u=this.out;if(!u)return;u._c()};return ReplaceErrorOperator}();exports.ReplaceErrorOperator=ReplaceErrorOperator;var StartWithOperator=function(){function StartWithOperator(ins,value){this.ins=ins;this.value=value;this.type="startWith";this.out=exports.emptyListener}StartWithOperator.prototype._start=function(out){this.out=out;this.out._n(this.value);this.ins._add(out)};StartWithOperator.prototype._stop=function(){this.ins._remove(this.out);this.out=null};return StartWithOperator}();exports.StartWithOperator=StartWithOperator;var TakeOperator=function(){function TakeOperator(max,ins){this.max=max;this.ins=ins;this.type="take";this.out=null;this.taken=0}TakeOperator.prototype._start=function(out){this.out=out;this.ins._add(this)};TakeOperator.prototype._stop=function(){this.ins._remove(this);this.out=null;this.taken=0};TakeOperator.prototype._n=function(t){var u=this.out;if(!u)return;if(this.taken++<this.max-1){u._n(t)}else{u._n(t);u._c()}};TakeOperator.prototype._e=function(err){var u=this.out;if(!u)return;u._e(err)};TakeOperator.prototype._c=function(){var u=this.out;if(!u)return;u._c()};return TakeOperator}();exports.TakeOperator=TakeOperator;var Stream=function(){function Stream(producer){this._stopID=empty;this._prod=producer;this._ils=[];this._hil=null}Stream.prototype._n=function(t){var a=this._ils;var L=a.length;if(L==1)a[0]._n(t);else{var b=copy(a);for(var i=0;i<L;i++)b[i]._n(t)}var h=this._hil;if(h)h._n(t)};Stream.prototype._e=function(err){var a=this._ils;var L=a.length;if(L==1)a[0]._e(err);else{var b=copy(a);for(var i=0;i<L;i++)b[i]._e(err)}var h=this._hil;if(h)h._e(err);this._x()};Stream.prototype._c=function(){var a=this._ils;var L=a.length;if(L==1)a[0]._c();else{var b=copy(a);for(var i=0;i<L;i++)b[i]._c()}var h=this._hil;if(h)h._c();this._x()};Stream.prototype._x=function(){if(this._ils.length===0)return;if(this._prod)this._prod._stop();this._ils=[]};Stream.prototype.addListener=function(listener){if(typeof listener.next!=="function"||typeof listener.error!=="function"||typeof listener.complete!=="function"){throw new Error("stream.addListener() requires all three next, error, "+"and complete functions.")}listener._n=listener.next;listener._e=listener.error;listener._c=listener.complete;this._add(listener)};Stream.prototype.removeListener=function(listener){this._remove(listener)};Stream.prototype._add=function(il){var a=this._ils;a.push(il);if(a.length===1){if(this._stopID!==empty){clearTimeout(this._stopID);this._stopID=empty}var p=this._prod;if(p)p._start(this)}};Stream.prototype._remove=function(il){var a=this._ils;var i=a.indexOf(il);if(i>-1){a.splice(i,1);var p_1=this._prod;if(p_1&&a.length<=0){this._stopID=setTimeout(function(){return p_1._stop()})}}};Stream.prototype._setHIL=function(il){this._hil=il};Stream.prototype.ctor=function(){return this instanceof MemoryStream?MemoryStream:Stream};Stream.create=function(producer){if(producer){if(typeof producer.start!=="function"||typeof producer.stop!=="function"){throw new Error("producer requires both start and stop functions")}internalizeProducer(producer)}return new Stream(producer)};Stream.createWithMemory=function(producer){if(producer){internalizeProducer(producer)}return new MemoryStream(producer)};Stream.never=function(){return new Stream({_start:noop,_stop:noop})};Stream.empty=function(){return new Stream({_start:function(il){il._c()},_stop:noop})};Stream.throw=function(error){return new Stream({_start:function(il){il._e(error)},_stop:noop})};Stream.of=function(){var items=[];for(var _i=0;_i<arguments.length;_i++){items[_i-0]=arguments[_i]}return Stream.fromArray(items)};Stream.fromArray=function(array){return new Stream(new FromArrayProducer(array))};Stream.fromPromise=function(promise){return new Stream(new FromPromiseProducer(promise))};Stream.periodic=function(period){return new Stream(new PeriodicProducer(period))};Stream.merge=function(){var streams=[];for(var _i=0;_i<arguments.length;_i++){streams[_i-0]=arguments[_i]}return new Stream(new MergeProducer(streams))};Stream.prototype._map=function(project){var p=this._prod;var ctor=this.ctor();if(p instanceof FilterOperator){return new ctor(new FilterMapOperator(p.passes,project,p.ins))}if(p instanceof FilterMapOperator){return new ctor(new FilterMapOperator(p.passes,compose2(project,p.project),p.ins))}if(p instanceof MapOperator){return new ctor(new MapOperator(compose2(project,p.project),p.ins))}return new ctor(new MapOperator(project,this))};Stream.prototype.map=function(project){return this._map(project)};Stream.prototype.mapTo=function(projectedValue){var s=this.map(function(){return projectedValue});var op=s._prod;op.type=op.type.replace("map","mapTo");return s};Stream.prototype.filter=function(passes){var p=this._prod;if(p instanceof FilterOperator){return new Stream(new FilterOperator(and(passes,p.passes),p.ins))}return new Stream(new FilterOperator(passes,this))};Stream.prototype.take=function(amount){return new(this.ctor())(new TakeOperator(amount,this))};Stream.prototype.drop=function(amount){return new Stream(new DropOperator(amount,this))};Stream.prototype.last=function(){return new Stream(new LastOperator(this))};Stream.prototype.startWith=function(initial){return new MemoryStream(new StartWithOperator(this,initial))};Stream.prototype.endWhen=function(other){return new(this.ctor())(new EndWhenOperator(other,this))};Stream.prototype.fold=function(accumulate,seed){return new MemoryStream(new FoldOperator(accumulate,seed,this))};Stream.prototype.replaceError=function(replace){return new(this.ctor())(new ReplaceErrorOperator(replace,this))};Stream.prototype.flatten=function(){var p=this._prod;return new Stream(p instanceof MapOperator&&!(p instanceof FilterMapOperator)?new MapFlattenOperator(p):new FlattenOperator(this))};Stream.prototype.compose=function(operator){return operator(this)};Stream.prototype.remember=function(){var _this=this;return new MemoryStream({_start:function(il){var p=_this._prod;if(p)p._start(il)},_stop:function(){var p=_this._prod;if(p)p._stop()}})};Stream.prototype.debug=function(labelOrSpy){return new(this.ctor())(new DebugOperator(labelOrSpy,this))};Stream.prototype.imitate=function(other){if(other instanceof MemoryStream){throw new Error("A MemoryStream was given to imitate(), but it only "+"supports a Stream. Read more about this restriction here: "+"https://github.com/staltz/xstream#faq")}other._setHIL(this)};Stream.prototype.shamefullySendNext=function(value){this._n(value)};Stream.prototype.shamefullySendError=function(error){this._e(error)};Stream.prototype.shamefullySendComplete=function(){this._c()};Stream.combine=function combine(){var streams=[];for(var _i=0;_i<arguments.length;_i++){streams[_i-0]=arguments[_i]}return new Stream(new CombineProducer(streams))};return Stream}();exports.Stream=Stream;var MemoryStream=function(_super){__extends(MemoryStream,_super);function MemoryStream(producer){_super.call(this,producer);this._has=false}MemoryStream.prototype._n=function(x){this._v=x;this._has=true;_super.prototype._n.call(this,x)};MemoryStream.prototype._add=function(il){if(this._has){il._n(this._v)}_super.prototype._add.call(this,il)};MemoryStream.prototype._x=function(){this._has=false;_super.prototype._x.call(this)};MemoryStream.prototype.map=function(project){return this._map(project)};MemoryStream.prototype.mapTo=function(projectedValue){return _super.prototype.mapTo.call(this,projectedValue)};MemoryStream.prototype.take=function(amount){return _super.prototype.take.call(this,amount)};MemoryStream.prototype.endWhen=function(other){return _super.prototype.endWhen.call(this,other)};MemoryStream.prototype.replaceError=function(replace){return _super.prototype.replaceError.call(this,replace)};MemoryStream.prototype.debug=function(labelOrSpy){return _super.prototype.debug.call(this,labelOrSpy)};return MemoryStream}(Stream);exports.MemoryStream=MemoryStream;Object.defineProperty(exports,"__esModule",{value:true});exports.default=Stream},{}],2:[function(require,module,exports){"use strict";var core_1=require("./core");exports.Stream=core_1.Stream;exports.MemoryStream=core_1.MemoryStream;Object.defineProperty(exports,"__esModule",{value:true});exports.default=core_1.Stream},{"./core":1}]},{},[2])(2)}); |
@@ -1,3 +0,3 @@ | ||
import { Stream, MemoryStream, MimicStream, Listener, Producer, Operator } from './core'; | ||
export { Stream, MemoryStream, MimicStream, Listener, Producer, Operator }; | ||
import { Stream, MemoryStream, Listener, Producer, Operator } from './core'; | ||
export { Stream, MemoryStream, Listener, Producer, Operator }; | ||
export default Stream; |
@@ -5,5 +5,4 @@ "use strict"; | ||
exports.MemoryStream = core_1.MemoryStream; | ||
exports.MimicStream = core_1.MimicStream; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.default = core_1.Stream; | ||
//# sourceMappingURL=index.js.map |
{ | ||
"name": "xstream", | ||
"version": "4.0.4", | ||
"version": "5.0.2", | ||
"description": "An extremely intuitive, small, and fast functional reactive stream library for JavaScript", | ||
@@ -28,3 +28,3 @@ "main": "index.js", | ||
"preversion": "npm run readme && npm test", | ||
"version": "npm run dist && git add -A", | ||
"version": "npm run readme && npm run dist && git add -A", | ||
"postversion": "git push origin master && git push origin --tags && npm publish && npm run update-gh-pages", | ||
@@ -56,3 +56,3 @@ "update-gh-pages": "git checkout gh-pages && rm _includes/content.md && cp .ignore/content.md _includes/ && git commit -a -m \"update site\" && git push origin gh-pages && git checkout master", | ||
"ghooks": "^1.0.3", | ||
"markdown-doctest": "^0.6.0", | ||
"markdown-doctest": "^0.7.0", | ||
"markdox": "^0.1.10", | ||
@@ -62,3 +62,3 @@ "mkdirp": "^0.5.1", | ||
"strip-comments": "^0.4.4", | ||
"ts-node": "^0.5.5", | ||
"ts-node": "^0.9.0", | ||
"tslint": "^3.6.0", | ||
@@ -65,0 +65,0 @@ "typescript": "^1.8.9", |
@@ -33,2 +33,5 @@ var Benchmark = require('benchmark'); | ||
} | ||
function add3Arr(arr) { | ||
return arr[0] + arr[1] + arr[2]; | ||
} | ||
@@ -50,3 +53,3 @@ var xs1 = xs.fromArray(a); | ||
runners.runXStream(deferred, | ||
xs.combine(add3, xs1, xs2, xs3).filter(even)); | ||
xs.combine(xs1, xs2, xs3).map(add3Arr).filter(even)); | ||
}, options) | ||
@@ -53,0 +56,0 @@ .add('most', function(deferred) { |
152
README.md
@@ -72,3 +72,2 @@ <!-- 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/. --> | ||
- [`createWithMemory`](#createWithMemory) | ||
- [`createMimic`](#createMimic) | ||
- [`never`](#never) | ||
@@ -102,6 +101,6 @@ - [`empty`](#empty) | ||
- [`debug`](#debug) | ||
- [`imitate`](#imitate) | ||
- [`shamefullySendNext`](#shamefullySendNext) | ||
- [`shamefullySendError`](#shamefullySendError) | ||
- [`shamefullySendComplete`](#shamefullySendComplete) | ||
- [`imitate`](#imitate) | ||
@@ -258,11 +257,2 @@ # Overview | ||
### <a id="createMimic"></a> `createMimic()` | ||
Creates a new MimicStream, which can `imitate` another Stream. Only a | ||
MimicStream has the `imitate()` method. | ||
#### Returns: MimicStream | ||
- - - | ||
### <a id="never"></a> `never()` | ||
@@ -428,13 +418,12 @@ | ||
### <a id="combine"></a> `combine(project, stream1, stream2)` | ||
### <a id="combine"></a> `combine(stream1, stream2)` | ||
Combines multiple streams together to return a stream whose events are | ||
calculated from the latest events of each of the input streams. | ||
Combines multiple input streams together to return a stream whose events | ||
are arrays that collect the latest events from each input stream. | ||
*combine* remembers the most recent event from each of the input streams. | ||
When any of the input streams emits an event, that event together with all | ||
the other saved events are combined in the `project` function which should | ||
return a value. That value will be emitted on the output stream. It's | ||
essentially a way of mixing the events from multiple streams according to a | ||
formula. | ||
*combine* internally remembers the most recent event from each of the input | ||
streams. When any of the input streams emits an event, that event together | ||
with all the other saved events are combined into an array. That array will | ||
be emitted on the output stream. It's essentially a way of joining together | ||
the events from multiple streams. | ||
@@ -446,3 +435,3 @@ Marble diagram: | ||
----a-----b-----c--d------ | ||
combine((x,y) => x+y) | ||
combine | ||
----1a-2a-2b-3b-3c-3d-4d-- | ||
@@ -453,8 +442,4 @@ ``` | ||
- `project: Function` A function of type `(x: T1, y: T2) => R` or similar that takes the most recent events `x` and `y` from the input | ||
streams and returns a value. The output stream will emit that value. The | ||
number of arguments for this function should match the number of input | ||
streams. | ||
- `stream1: Stream` A stream to combine together with other streams. | ||
- `stream2: Stream` A stream to combine together with other streams. Two or more streams may be given as arguments. | ||
- `stream2: Stream` A stream to combine together with other streams. Multiple streams, not just two, may be given as arguments. | ||
@@ -811,50 +796,11 @@ #### Returns: Stream | ||
### <a id="shamefullySendNext"></a> `shamefullySendNext(value)` | ||
Forces the Stream to emit the given value to its listeners. | ||
As the name indicates, if you use this, you are most likely doing something | ||
The Wrong Way. Please try to understand the reactive way before using this | ||
method. Use it only when you know what you are doing. | ||
#### Arguments: | ||
- `value` The "next" value you want to broadcast to all listeners of this Stream. | ||
- - - | ||
### <a id="shamefullySendError"></a> `shamefullySendError(error)` | ||
Forces the Stream to emit the given error to its listeners. | ||
As the name indicates, if you use this, you are most likely doing something | ||
The Wrong Way. Please try to understand the reactive way before using this | ||
method. Use it only when you know what you are doing. | ||
#### Arguments: | ||
- `error: any` The error you want to broadcast to all the listeners of this Stream. | ||
- - - | ||
### <a id="shamefullySendComplete"></a> `shamefullySendComplete()` | ||
Forces the Stream to emit the "completed" event to its listeners. | ||
As the name indicates, if you use this, you are most likely doing something | ||
The Wrong Way. Please try to understand the reactive way before using this | ||
method. Use it only when you know what you are doing. | ||
- - - | ||
### <a id="imitate"></a> `imitate(other)` | ||
This method exists only on a MimicStream, which is created through | ||
`xs.createMimic()`. *imitate* changes this current MimicStream to behave | ||
like the `other` given stream. | ||
*imitate* changes this current Stream to emit the same events that the | ||
`other` given Stream does. This method returns nothing. | ||
The `imitate` method and the `MimicStream` type exist to allow one thing: | ||
**circular dependency of streams**. For instance, let's imagine that for | ||
some reason you need to create a circular dependency where stream `first$` | ||
depends on stream `second$` which in turn depends on `first$`: | ||
This method exists to allow one thing: **circular dependency of streams**. | ||
For instance, let's imagine that for some reason you need to create a | ||
circular dependency where stream `first$` depends on stream `second$` | ||
which in turn depends on `first$`: | ||
@@ -870,3 +816,3 @@ <!-- skip-example --> | ||
However, that is invalid JavaScript, because `second$` is undefined | ||
on the first line. This is how a MimicStream and imitate can help solve it: | ||
on the first line. This is how *imitate* can help solve it: | ||
@@ -876,13 +822,13 @@ ```js | ||
var secondMimic$ = xs.createMimic(); | ||
var first$ = secondMimic$.map(x => x * 10).take(3); | ||
var secondProxy$ = xs.create(); | ||
var first$ = secondProxy$.map(x => x * 10).take(3); | ||
var second$ = first$.map(x => x + 1).startWith(1).compose(delay(100)); | ||
secondMimic$.imitate(second$); | ||
secondProxy$.imitate(second$); | ||
``` | ||
We create `secondMimic$` before the others, so it can be used in the | ||
We create `secondProxy$` before the others, so it can be used in the | ||
declaration of `first$`. Then, after both `first$` and `second$` are | ||
defined, we hook `secondMimic$` with `second$` with `imitate()` to tell | ||
defined, we hook `secondProxy$` with `second$` with `imitate()` to tell | ||
that they are "the same". `imitate` will not trigger the start of any | ||
stream, it simply forwards listeners of `secondMimic$` to `second$`. | ||
stream, it just binds `secondProxy$` and `second$` together. | ||
@@ -895,12 +841,8 @@ The following is an example where `imitate()` is important in Cycle.js | ||
```js | ||
const childActionMimic$ = xs.createMimic(); | ||
const parent = Parent({...sources, childAction$: childActionMimic$}); | ||
const childActionProxy$ = xs.create(); | ||
const parent = Parent({...sources, childAction$: childActionProxy$}); | ||
const childAction$ = parent.state$.map(s => s.child.action$).flatten(); | ||
childActionMimic$.imitate(childAction$); | ||
childActionProxy$.imitate(childAction$); | ||
``` | ||
The *imitate* method returns nothing. Instead, it changes the behavior of | ||
the current stream, making it re-emit whatever events are emitted by the | ||
given `other` stream. | ||
Note, though, that **`imitate()` does not support MemoryStreams**. If we | ||
@@ -918,3 +860,3 @@ would attempt to imitate a MemoryStream in a circular dependency, we would | ||
represents an event stream, and that would be a candidate for creating a | ||
MimicStream which then imitates the real event stream. | ||
proxy Stream which then imitates the target Stream. | ||
@@ -927,2 +869,40 @@ #### Arguments: | ||
### <a id="shamefullySendNext"></a> `shamefullySendNext(value)` | ||
Forces the Stream to emit the given value to its listeners. | ||
As the name indicates, if you use this, you are most likely doing something | ||
The Wrong Way. Please try to understand the reactive way before using this | ||
method. Use it only when you know what you are doing. | ||
#### Arguments: | ||
- `value` The "next" value you want to broadcast to all listeners of this Stream. | ||
- - - | ||
### <a id="shamefullySendError"></a> `shamefullySendError(error)` | ||
Forces the Stream to emit the given error to its listeners. | ||
As the name indicates, if you use this, you are most likely doing something | ||
The Wrong Way. Please try to understand the reactive way before using this | ||
method. Use it only when you know what you are doing. | ||
#### Arguments: | ||
- `error: any` The error you want to broadcast to all the listeners of this Stream. | ||
- - - | ||
### <a id="shamefullySendComplete"></a> `shamefullySendComplete()` | ||
Forces the Stream to emit the "completed" event to its listeners. | ||
As the name indicates, if you use this, you are most likely doing something | ||
The Wrong Way. Please try to understand the reactive way before using this | ||
method. Use it only when you know what you are doing. | ||
- - - | ||
# Extra operators and factories | ||
@@ -929,0 +909,0 @@ |
392
src/core.ts
@@ -65,14 +65,2 @@ import {Promise} from 'es6-promise'; | ||
function invoke(f: Function, args: Array<any>) { | ||
switch (args.length) { | ||
case 0: return f(); | ||
case 1: return f(args[0]); | ||
case 2: return f(args[0], args[1]); | ||
case 3: return f(args[0], args[1], args[2]); | ||
case 4: return f(args[0], args[1], args[2], args[3]); | ||
case 5: return f(args[0], args[1], args[2], args[3], args[4]); | ||
default: return f.apply(void 0, args); | ||
} | ||
} | ||
function compose2<T, U>(f1: (t: T) => any, f2: (t: T) => any): (t: T) => any { | ||
@@ -90,35 +78,80 @@ return function composedFn(arg: T): any { | ||
export interface CombineProjectFunction { | ||
<T1, T2, R>(v1: T1, v2: T2): R; | ||
<T1, T2, T3, R>(v1: T1, v2: T2, v3: T3): R; | ||
<T1, T2, T3, T4, R>(v1: T1, v2: T2, v3: T3, v4: T4): R; | ||
<T1, T2, T3, T4, T5, R>(v1: T1, v2: T2, v3: T3, v4: T4, v5: T5): R; | ||
<T1, T2, T3, T4, T5, T6, R>(v1: T1, v2: T2, v3: T3, v4: T4, v5: T5, v6: T6): R; | ||
<R>(...values: Array<any>): R; | ||
export class MergeProducer<T> implements InternalProducer<T>, InternalListener<T> { | ||
public type = 'merge'; | ||
private out: InternalListener<T> = emptyListener; | ||
private ac: number; // ac is activeCount, starts initialized | ||
constructor(public streams: Array<Stream<T>>) { | ||
this.ac = streams.length; | ||
} | ||
_start(out: InternalListener<T>): void { | ||
this.out = out; | ||
const s = this.streams; | ||
const L = s.length; | ||
for (let i = 0; i < L; i++) { | ||
s[i]._add(this); | ||
} | ||
} | ||
_stop(): void { | ||
const s = this.streams; | ||
const L = s.length; | ||
for (let i = 0; i < L; i++) { | ||
s[i]._remove(this); | ||
} | ||
this.out = null; | ||
this.ac = L; | ||
} | ||
_n(t: T) { | ||
const u = this.out; | ||
if (!u) return; | ||
u._n(t); | ||
} | ||
_e(err: any) { | ||
const u = this.out; | ||
if (!u) return; | ||
u._e(err); | ||
} | ||
_c() { | ||
if (--this.ac === 0) { | ||
const u = this.out; | ||
if (!u) return; | ||
u._c(); | ||
} | ||
} | ||
} | ||
export interface CombineFactorySignature { | ||
<T1, T2, R>( | ||
project: (t1: T1, t2: T2) => R, | ||
stream1: Stream<T1>, | ||
stream2: Stream<T2>): Stream<R>; | ||
<T1, T2, T3, R>( | ||
project: (t1: T1, t2: T2, t3: T3) => R, | ||
stream1: Stream<T1>, | ||
stream2: Stream<T2>, | ||
stream3: Stream<T3>): Stream<R>; | ||
<T1, T2, T3, T4, R>( | ||
project: (t1: T1, t2: T2, t3: T3, t4: T4) => R, | ||
stream1: Stream<T1>, | ||
stream2: Stream<T2>, | ||
stream3: Stream<T3>, | ||
stream4: Stream<T4>): Stream<R>; | ||
<T1, T2, T3, T4, T5, R>( | ||
project: (t1: T1, t2: T2, t3: T3, t4: T4, t5: T5) => R, | ||
stream1: Stream<T1>, | ||
stream2: Stream<T2>, | ||
stream3: Stream<T3>, | ||
stream4: Stream<T4>, | ||
stream5: Stream<T5>): Stream<R>; | ||
<R>(project: (...args: Array<any>) => R, ...streams: Array<Stream<any>>): Stream<R>; | ||
export interface CombineSignature { | ||
(): Stream<Array<any>>; | ||
<T1>(s1: Stream<T1>): Stream<[T1]>; | ||
<T1, T2>( | ||
s1: Stream<T1>, | ||
s2: Stream<T2>): Stream<[T1, T2]>; | ||
<T1, T2, T3>( | ||
s1: Stream<T1>, | ||
s2: Stream<T2>, | ||
s3: Stream<T3>): Stream<[T1, T2, T3]>; | ||
<T1, T2, T3, T4>( | ||
s1: Stream<T1>, | ||
s2: Stream<T2>, | ||
s3: Stream<T3>, | ||
s4: Stream<T4>): Stream<[T1, T2, T3, T4]>; | ||
<T1, T2, T3, T4, T5>( | ||
s1: Stream<T1>, | ||
s2: Stream<T2>, | ||
s3: Stream<T3>, | ||
s4: Stream<T4>, | ||
s5: Stream<T5>): Stream<[T1, T2, T3, T4, T5]>; | ||
<T1, T2, T3, T4, T5, T6>( | ||
s1: Stream<T1>, | ||
s2: Stream<T2>, | ||
s3: Stream<T3>, | ||
s4: Stream<T4>, | ||
s5: Stream<T5>, | ||
s6: Stream<T6>): Stream<[T1, T2, T3, T4, T5, T6]>; | ||
(...stream: Array<Stream<any>>): Stream<Array<any>>; | ||
} | ||
@@ -136,7 +169,3 @@ | ||
if (p.up(t, this.i)) { | ||
try { | ||
out._n(invoke(p.project, p.vals)); | ||
} catch (e) { | ||
out._e(e); | ||
} | ||
out._n(p.vals); | ||
} | ||
@@ -160,12 +189,11 @@ } | ||
export class CombineProducer<R> implements InternalProducer<R> { | ||
export class CombineProducer<R> implements InternalProducer<Array<R>> { | ||
public type = 'combine'; | ||
public out: InternalListener<R> = emptyListener; | ||
public out: InternalListener<Array<R>> = emptyListener; | ||
public ils: Array<CombineListener<any>> = []; | ||
public ac: number; // ac is "active count", num of streams still not completed | ||
public left: number; // number of streams that still need to emit a value | ||
public vals: Array<any>; | ||
public vals: Array<R>; | ||
constructor(public project: CombineProjectFunction, | ||
public streams: Array<Stream<any>>) { | ||
constructor(public streams: Array<Stream<any>>) { | ||
const n = this.ac = this.left = streams.length; | ||
@@ -185,7 +213,10 @@ const vals = this.vals = new Array(n); | ||
_start(out: InternalListener<R>): void { | ||
_start(out: InternalListener<Array<R>>): void { | ||
this.out = out; | ||
const s = this.streams; | ||
const n = s.length; | ||
if (n === 0) this.zero(out); else { | ||
if (n === 0) { | ||
out._n(this.vals); | ||
out._c(); | ||
} else { | ||
for (let i = 0; i < n; i++) { | ||
@@ -208,11 +239,2 @@ s[i]._add(new CombineListener(i, this)); | ||
} | ||
zero(out: InternalListener<R>): void { | ||
try { | ||
out._n(this.project<R>()); | ||
out._c(); | ||
} catch (e) { | ||
out._e(e); | ||
} | ||
} | ||
} | ||
@@ -267,51 +289,2 @@ | ||
export class MergeProducer<T> implements InternalProducer<T>, InternalListener<T> { | ||
public type = 'merge'; | ||
private out: InternalListener<T> = emptyListener; | ||
private ac: number; // ac is activeCount, starts initialized | ||
constructor(public streams: Array<Stream<T>>) { | ||
this.ac = streams.length; | ||
} | ||
_start(out: InternalListener<T>): void { | ||
this.out = out; | ||
const s = this.streams; | ||
const L = s.length; | ||
for (let i = 0; i < L; i++) { | ||
s[i]._add(this); | ||
} | ||
} | ||
_stop(): void { | ||
const s = this.streams; | ||
const L = s.length; | ||
for (let i = 0; i < L; i++) { | ||
s[i]._remove(this); | ||
} | ||
this.out = null; | ||
this.ac = L; | ||
} | ||
_n(t: T) { | ||
const u = this.out; | ||
if (!u) return; | ||
u._n(t); | ||
} | ||
_e(err: any) { | ||
const u = this.out; | ||
if (!u) return; | ||
u._e(err); | ||
} | ||
_c() { | ||
if (--this.ac === 0) { | ||
const u = this.out; | ||
if (!u) return; | ||
u._c(); | ||
} | ||
} | ||
} | ||
export class PeriodicProducer implements InternalProducer<number> { | ||
@@ -920,3 +893,2 @@ public type = 'periodic'; | ||
u._c(); | ||
this._stop(); | ||
} | ||
@@ -940,2 +912,3 @@ } | ||
protected _ils: Array<InternalListener<T>>; // 'ils' = Internal listeners | ||
protected _hil: InternalListener<T>; // 'hil' = Hidden Internal Listener | ||
protected _stopID: any = empty; | ||
@@ -947,2 +920,3 @@ protected _prod: InternalProducer<T>; | ||
this._ils = []; | ||
this._hil = null; | ||
} | ||
@@ -957,2 +931,4 @@ | ||
} | ||
const h = this._hil; | ||
if (h) h._n(t); | ||
} | ||
@@ -967,2 +943,4 @@ | ||
} | ||
const h = this._hil; | ||
if (h) h._e(err); | ||
this._x(); | ||
@@ -978,2 +956,4 @@ } | ||
} | ||
const h = this._hil; | ||
if (h) h._c(); | ||
this._x(); | ||
@@ -1040,2 +1020,6 @@ } | ||
_setHIL(il: InternalListener<T>): void { | ||
this._hil = il; | ||
} | ||
private ctor(): typeof Stream { | ||
@@ -1080,13 +1064,2 @@ return this instanceof MemoryStream ? MemoryStream : Stream; | ||
/** | ||
* Creates a new MimicStream, which can `imitate` another Stream. Only a | ||
* MimicStream has the `imitate()` method. | ||
* | ||
* @factory true | ||
* @return {MimicStream} | ||
*/ | ||
static createMimic<T>(): MimicStream<T> { | ||
return new MimicStream<T>(); | ||
} | ||
/** | ||
* Creates a Stream that does nothing when started. It never emits any event. | ||
@@ -1259,11 +1232,10 @@ * | ||
/** | ||
* Combines multiple streams together to return a stream whose events are | ||
* calculated from the latest events of each of the input streams. | ||
* Combines multiple input streams together to return a stream whose events | ||
* are arrays that collect the latest events from each input stream. | ||
* | ||
* *combine* remembers the most recent event from each of the input streams. | ||
* When any of the input streams emits an event, that event together with all | ||
* the other saved events are combined in the `project` function which should | ||
* return a value. That value will be emitted on the output stream. It's | ||
* essentially a way of mixing the events from multiple streams according to a | ||
* formula. | ||
* *combine* internally remembers the most recent event from each of the input | ||
* streams. When any of the input streams emits an event, that event together | ||
* with all the other saved events are combined into an array. That array will | ||
* be emitted on the output stream. It's essentially a way of joining together | ||
* the events from multiple streams. | ||
* | ||
@@ -1275,3 +1247,3 @@ * Marble diagram: | ||
* ----a-----b-----c--d------ | ||
* combine((x,y) => x+y) | ||
* combine | ||
* ----1a-2a-2b-3b-3c-3d-4d-- | ||
@@ -1281,16 +1253,10 @@ * ``` | ||
* @factory true | ||
* @param {Function} project A function of type `(x: T1, y: T2) => R` or | ||
* similar that takes the most recent events `x` and `y` from the input | ||
* streams and returns a value. The output stream will emit that value. The | ||
* number of arguments for this function should match the number of input | ||
* streams. | ||
* @param {Stream} stream1 A stream to combine together with other streams. | ||
* @param {Stream} stream2 A stream to combine together with other streams. | ||
* Two or more streams may be given as arguments. | ||
* Multiple streams, not just two, may be given as arguments. | ||
* @return {Stream} | ||
*/ | ||
static combine: CombineFactorySignature = | ||
function combine<R>(project: CombineProjectFunction, | ||
...streams: Array<Stream<any>>): Stream<R> { | ||
return new Stream<R>(new CombineProducer<R>(project, streams)); | ||
static combine: CombineSignature = <CombineSignature> | ||
function combine(...streams: Array<Stream<any>>): Stream<Array<any>> { | ||
return new Stream<Array<any>>(new CombineProducer<any>(streams)); | ||
}; | ||
@@ -1661,69 +1627,10 @@ | ||
/** | ||
* Forces the Stream to emit the given value to its listeners. | ||
* *imitate* changes this current Stream to emit the same events that the | ||
* `other` given Stream does. This method returns nothing. | ||
* | ||
* As the name indicates, if you use this, you are most likely doing something | ||
* The Wrong Way. Please try to understand the reactive way before using this | ||
* method. Use it only when you know what you are doing. | ||
* This method exists to allow one thing: **circular dependency of streams**. | ||
* For instance, let's imagine that for some reason you need to create a | ||
* circular dependency where stream `first$` depends on stream `second$` | ||
* which in turn depends on `first$`: | ||
* | ||
* @param value The "next" value you want to broadcast to all listeners of | ||
* this Stream. | ||
*/ | ||
shamefullySendNext(value: T) { | ||
this._n(value); | ||
} | ||
/** | ||
* Forces the Stream to emit the given error to its listeners. | ||
* | ||
* As the name indicates, if you use this, you are most likely doing something | ||
* The Wrong Way. Please try to understand the reactive way before using this | ||
* method. Use it only when you know what you are doing. | ||
* | ||
* @param {any} error The error you want to broadcast to all the listeners of | ||
* this Stream. | ||
*/ | ||
shamefullySendError(error: any) { | ||
this._e(error); | ||
} | ||
/** | ||
* Forces the Stream to emit the "completed" event to its listeners. | ||
* | ||
* As the name indicates, if you use this, you are most likely doing something | ||
* The Wrong Way. Please try to understand the reactive way before using this | ||
* method. Use it only when you know what you are doing. | ||
*/ | ||
shamefullySendComplete() { | ||
this._c(); | ||
} | ||
} | ||
export class MimicStream<T> extends Stream<T> { | ||
private _target: Stream<T>; | ||
constructor() { | ||
super(); | ||
} | ||
_add(il: InternalListener<T>): void { | ||
const t = this._target; | ||
if (!t) return; | ||
t._add(il); | ||
} | ||
_remove(il: InternalListener<T>): void { | ||
const t = this._target; | ||
if (!t) return; | ||
t._remove(il); | ||
} | ||
/** | ||
* This method exists only on a MimicStream, which is created through | ||
* `xs.createMimic()`. *imitate* changes this current MimicStream to behave | ||
* like the `other` given stream. | ||
* | ||
* The `imitate` method and the `MimicStream` type exist to allow one thing: | ||
* **circular dependency of streams**. For instance, let's imagine that for | ||
* some reason you need to create a circular dependency where stream `first$` | ||
* depends on stream `second$` which in turn depends on `first$`: | ||
* | ||
* <!-- skip-example --> | ||
@@ -1738,3 +1645,3 @@ * ```js | ||
* However, that is invalid JavaScript, because `second$` is undefined | ||
* on the first line. This is how a MimicStream and imitate can help solve it: | ||
* on the first line. This is how *imitate* can help solve it: | ||
* | ||
@@ -1744,13 +1651,13 @@ * ```js | ||
* | ||
* var secondMimic$ = xs.createMimic(); | ||
* var first$ = secondMimic$.map(x => x * 10).take(3); | ||
* var secondProxy$ = xs.create(); | ||
* var first$ = secondProxy$.map(x => x * 10).take(3); | ||
* var second$ = first$.map(x => x + 1).startWith(1).compose(delay(100)); | ||
* secondMimic$.imitate(second$); | ||
* secondProxy$.imitate(second$); | ||
* ``` | ||
* | ||
* We create `secondMimic$` before the others, so it can be used in the | ||
* We create `secondProxy$` before the others, so it can be used in the | ||
* declaration of `first$`. Then, after both `first$` and `second$` are | ||
* defined, we hook `secondMimic$` with `second$` with `imitate()` to tell | ||
* defined, we hook `secondProxy$` with `second$` with `imitate()` to tell | ||
* that they are "the same". `imitate` will not trigger the start of any | ||
* stream, it simply forwards listeners of `secondMimic$` to `second$`. | ||
* stream, it just binds `secondProxy$` and `second$` together. | ||
* | ||
@@ -1763,12 +1670,8 @@ * The following is an example where `imitate()` is important in Cycle.js | ||
* ```js | ||
* const childActionMimic$ = xs.createMimic(); | ||
* const parent = Parent({...sources, childAction$: childActionMimic$}); | ||
* const childActionProxy$ = xs.create(); | ||
* const parent = Parent({...sources, childAction$: childActionProxy$}); | ||
* const childAction$ = parent.state$.map(s => s.child.action$).flatten(); | ||
* childActionMimic$.imitate(childAction$); | ||
* childActionProxy$.imitate(childAction$); | ||
* ``` | ||
* | ||
* The *imitate* method returns nothing. Instead, it changes the behavior of | ||
* the current stream, making it re-emit whatever events are emitted by the | ||
* given `other` stream. | ||
* | ||
* Note, though, that **`imitate()` does not support MemoryStreams**. If we | ||
@@ -1786,3 +1689,3 @@ * would attempt to imitate a MemoryStream in a circular dependency, we would | ||
* represents an event stream, and that would be a candidate for creating a | ||
* MimicStream which then imitates the real event stream. | ||
* proxy Stream which then imitates the target Stream. | ||
* | ||
@@ -1798,4 +1701,43 @@ * @param {Stream} other The stream to imitate on the current one. Must not be | ||
} | ||
this._target = other; | ||
other._setHIL(this); | ||
} | ||
/** | ||
* Forces the Stream to emit the given value to its listeners. | ||
* | ||
* As the name indicates, if you use this, you are most likely doing something | ||
* The Wrong Way. Please try to understand the reactive way before using this | ||
* method. Use it only when you know what you are doing. | ||
* | ||
* @param value The "next" value you want to broadcast to all listeners of | ||
* this Stream. | ||
*/ | ||
shamefullySendNext(value: T) { | ||
this._n(value); | ||
} | ||
/** | ||
* Forces the Stream to emit the given error to its listeners. | ||
* | ||
* As the name indicates, if you use this, you are most likely doing something | ||
* The Wrong Way. Please try to understand the reactive way before using this | ||
* method. Use it only when you know what you are doing. | ||
* | ||
* @param {any} error The error you want to broadcast to all the listeners of | ||
* this Stream. | ||
*/ | ||
shamefullySendError(error: any) { | ||
this._e(error); | ||
} | ||
/** | ||
* Forces the Stream to emit the "completed" event to its listeners. | ||
* | ||
* As the name indicates, if you use this, you are most likely doing something | ||
* The Wrong Way. Please try to understand the reactive way before using this | ||
* method. Use it only when you know what you are doing. | ||
*/ | ||
shamefullySendComplete() { | ||
this._c(); | ||
} | ||
} | ||
@@ -1802,0 +1744,0 @@ |
@@ -1,3 +0,3 @@ | ||
import {Stream, MemoryStream, MimicStream, Listener, Producer, Operator} from './core'; | ||
export {Stream, MemoryStream, MimicStream, Listener, Producer, Operator}; | ||
import {Stream, MemoryStream, Listener, Producer, Operator} from './core'; | ||
export {Stream, MemoryStream, Listener, Producer, Operator}; | ||
export default Stream; |
@@ -10,7 +10,9 @@ /// <reference path="../../typings/globals/mocha/index.d.ts" /> | ||
const stream2 = xs.periodic(120).take(2); | ||
const stream = xs.combine((x, y) => `${x}${y}`, stream1, stream2); | ||
let expected = ['00', '10', '11']; | ||
const stream = xs.combine(stream1, stream2); | ||
let expected = [[0,0], [1,0], [1,1]]; | ||
stream.addListener({ | ||
next: (x) => { | ||
assert.equal(x, expected.shift()); | ||
const e = expected.shift(); | ||
assert.equal(x[0], e[0]); | ||
assert.equal(x[1], e[1]); | ||
}, | ||
@@ -36,6 +38,3 @@ error: done, | ||
const combined: Stream<string> = xs.combine( | ||
(a, b) => a.slice(2) + b.slice(2), | ||
stream1, stream2 | ||
); | ||
const combined: Stream<[string, string]> = xs.combine(stream1, stream2); | ||
done(); | ||
@@ -47,3 +46,3 @@ }); | ||
const stream2 = xs.periodic(50).take(4); | ||
const stream = xs.combine((x, y) => `${x}${y}`, stream1, stream2); | ||
const stream = xs.combine(stream1, stream2).map(arr => arr.join('')) | ||
let expected = ['00', '01', '02', '03']; | ||
@@ -62,32 +61,12 @@ stream.addListener({ | ||
it('should propagate user mistakes in project as errors', (done) => { | ||
const stream1 = xs.periodic(30).take(1); | ||
const stream2 = xs.periodic(50).take(4); | ||
const stream = xs.combine( | ||
(x, y) => <number> <any> (<string> <any> x).toLowerCase(), | ||
stream1, stream2 | ||
); | ||
stream.addListener({ | ||
next: () => done('next should not be called'), | ||
error: (err) => { | ||
assert.notStrictEqual(err.message.match(/is not a function$/), null); | ||
done(); | ||
}, | ||
complete: () => { | ||
done('complete should not be called'); | ||
}, | ||
}); | ||
}); | ||
it('should emit an empty array if combining zero streams', (done) => { | ||
const stream = xs.combine(); | ||
it('should handle a group of zero streams', (done) => { | ||
const stream = xs.combine<string>(() => 'hi'); | ||
let expected = ['hi']; | ||
stream.addListener({ | ||
next: (x) => { | ||
assert.equal(x, expected.shift()); | ||
next: (a) => { | ||
assert.equal(Array.isArray(a), true); | ||
assert.equal(a.length, 0); | ||
}, | ||
error: done, | ||
complete: () => { | ||
assert.equal(expected.length, 0); | ||
done(); | ||
@@ -108,6 +87,4 @@ }, | ||
.map(x => { | ||
return xs.combine( | ||
(...args: Array<number>) => '' + x + args.join(''), | ||
...arrayInners | ||
); | ||
return xs.combine(...arrayInners) | ||
.map(combination => `${x}${combination.join('')}`); | ||
}) | ||
@@ -158,3 +135,3 @@ .flatten(); | ||
const input2 = xs.periodic(80).take(3); | ||
const stream: Stream<number> = xs.combine((x, y) => x + y, input1, input2); | ||
const stream: Stream<[number, number]> = xs.combine(input1, input2); | ||
assert.strictEqual(stream instanceof Stream, true); | ||
@@ -167,3 +144,3 @@ done(); | ||
const input2 = xs.periodic(80).take(3).remember(); | ||
const stream: Stream<number> = xs.combine((x, y) => x + y, input1, input2); | ||
const stream: Stream<[number, number]> = xs.combine(input1, input2); | ||
assert.strictEqual(stream instanceof Stream, true); | ||
@@ -170,0 +147,0 @@ done(); |
/// <reference path="../../typings/globals/mocha/index.d.ts" /> | ||
/// <reference path="../../typings/globals/node/index.d.ts" /> | ||
import xs, {Stream, MemoryStream} from '../../src/index'; | ||
import xs, {Producer, Listener, Stream, MemoryStream} from '../../src/index'; | ||
import delay from '../../src/extra/delay'; | ||
import * as assert from 'assert'; | ||
describe('MimicStream.prototype.imitate', () => { | ||
it('should make the mimic stream act like the given stream', (done) => { | ||
const stream = xs.periodic(50).take(3); | ||
const proxyStream = xs.createMimic<number>(); | ||
proxyStream.imitate(stream); | ||
describe('Stream.prototype.imitate', () => { | ||
it('should be able to model a circular dependency in the stream graph', (done) => { | ||
const fakeSecond = xs.create<number>(); | ||
const first = fakeSecond.map(x => x * 10).take(3); | ||
const second = first.map(x => x + 1).startWith(1).compose(delay<number>(1)); | ||
fakeSecond.imitate(second); | ||
const expected = [1, 11, 111, 1111]; | ||
const expected = [0, 1, 2]; | ||
second.addListener({ | ||
next: (x: number) => { | ||
assert.equal(x, expected.shift()); | ||
}, | ||
error: (err: any) => done(err), | ||
complete: () => { | ||
assert.equal(expected.length, 0); | ||
done(); | ||
}, | ||
}); | ||
}); | ||
it('should broadcast the source stream to multiple listeners', (done) => { | ||
const fakeSecond = xs.create<number>(); | ||
const first = fakeSecond.map(x => x * 10).take(3); | ||
const second = first.map(x => x + 1).startWith(1).compose(delay<number>(100)); | ||
fakeSecond.imitate(second); | ||
const expected1 = [1, 11, 111, 1111]; | ||
const expected2 = [11, 111, 1111]; | ||
let completed1 = false; | ||
let completed2 = false; | ||
let listener1 = { | ||
next: (x: number) => { | ||
assert.equal(x, expected1.shift()); | ||
}, | ||
error: (err: any) => done(err), | ||
complete: () => { | ||
completed1 = true; | ||
} | ||
}; | ||
fakeSecond.addListener(listener1); | ||
second.addListener({ next: () => { }, error: () => { }, complete: () => { } }); | ||
let listener2 = { | ||
next: (x: number) => { | ||
assert.equal(x, expected2.shift()); | ||
}, | ||
error: (err: any) => done(err), | ||
complete: () => { | ||
completed2 = true; | ||
} | ||
}; | ||
setTimeout(() => { | ||
proxyStream.addListener({ | ||
next: (x: number) => { | ||
assert.equal(x, expected.shift()); | ||
}, | ||
error: (err: any) => done(err), | ||
complete: () => { | ||
assert.equal(expected.length, 0); | ||
fakeSecond.addListener(listener2); | ||
}, 150); | ||
setTimeout(() => { | ||
fakeSecond.removeListener(listener1); | ||
fakeSecond.removeListener(listener2); | ||
assert.equal(expected1.length, 0); | ||
assert.equal(expected2.length, 0); | ||
assert.equal(completed1, true); | ||
assert.equal(completed2, true); | ||
done(); | ||
}, 600); | ||
}); | ||
it('should not cause leaked cyclic executions', (done) => { | ||
const expectedProxy = [2, 4, 8, 16, 32 /* inertia due to stopping on next tick */]; | ||
const expectedResult = [2, 4, 8, 16]; | ||
const proxy$ = xs.create<number>(); | ||
const source$ = proxy$.startWith(1).map(x => x * 2) | ||
.debug(x => { | ||
try { | ||
assert.equal(expectedProxy.length > 0, true, | ||
'should be expecting the next value ' + x); | ||
assert.equal(x, expectedProxy.shift()); | ||
} catch (err) { | ||
done(err); | ||
} | ||
}); | ||
const result$ = source$.compose(delay(100)).compose(s => <Stream<number>> s); | ||
proxy$.imitate(result$) | ||
result$.take(4).addListener({ | ||
next: (x: number) => { | ||
assert.equal(x, expectedResult.shift()); | ||
}, | ||
error: (err: any) => done(err), | ||
complete: () => { | ||
assert.equal(expectedProxy.length, 1); // still waiting for 32 | ||
assert.equal(expectedResult.length, 0); | ||
setTimeout(() => { | ||
done(); | ||
}, | ||
}); | ||
}, 125); | ||
}, 1000); | ||
}, | ||
}); | ||
}); | ||
it('should not by itself start a the imitated stream execution', (done) => { | ||
it('should not by itself start the target stream execution', (done) => { | ||
let nextDelivered = false; | ||
@@ -32,3 +112,3 @@ const stream = xs.periodic(50).take(3).debug(() => { | ||
}); | ||
const proxyStream = xs.createMimic<number>(); | ||
const proxyStream = xs.create<number>(); | ||
@@ -46,3 +126,3 @@ setTimeout(() => { | ||
assert.strictEqual(stream instanceof MemoryStream, true); | ||
const proxyStream = xs.createMimic<number>(); | ||
const proxyStream = xs.create<number>(); | ||
assert.throws(() => { | ||
@@ -49,0 +129,0 @@ proxyStream.imitate(stream); |
@@ -10,3 +10,2 @@ /// <reference path="../typings/globals/mocha/index.d.ts" /> | ||
assert.equal(typeof xs.createWithMemory, 'function'); | ||
assert.equal(typeof xs.createMimic, 'function'); | ||
assert.equal(typeof xs.never, 'function'); | ||
@@ -40,2 +39,3 @@ assert.equal(typeof xs.empty, 'function'); | ||
assert.equal(typeof stream.debug, 'function'); | ||
assert.equal(typeof stream.imitate, 'function'); | ||
}); | ||
@@ -354,3 +354,3 @@ | ||
} catch (e) { | ||
assert.equal(e.message, 'stream.addListener() requires all three ' + | ||
assert.equal(e.message, 'stream.addListener() requires all three ' + | ||
'next, error, and complete functions.'); | ||
@@ -357,0 +357,0 @@ done(); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
720379
138
12842
942