Skip to content

Commit f1b5a1b

Browse files
committed
Merge tag '0.3.2'
v0.3.2
2 parents 49ede99 + 8765387 commit f1b5a1b

37 files changed

+277
-155
lines changed

README.md

Lines changed: 0 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -10,45 +10,6 @@ npm i servable --save
1010

1111
---------
1212

13-
It can be used like so:
14-
15-
```
16-
const Observable = require('servable').Observable;
17-
18-
const countObservable$ = Observable.interval(1000, 1);
19-
20-
const countSubscription = countObservable$
21-
.take(10)
22-
.map((n) => n * 5)
23-
.filter((n) => n > 10)
24-
.subscribe({
25-
next (number) {
26-
console.log('NEXT NUMBER: ', number);
27-
},
28-
29-
error (errors) {
30-
console.warn('I HAVE ERRORS', errors)
31-
},
32-
33-
complete () {
34-
console.log('I AM COMPLETE');
35-
}
36-
});
37-
```
38-
39-
This will log out to the console (if subscribe like above is called):
40-
```
41-
NEXT NUMBER: 15
42-
NEXT NUMBER: 20 // after a 1 second delay
43-
NEXT NUMBER: 25 // after a 1 second delay
44-
NEXT NUMBER: 30 // after a 1 second delay
45-
NEXT NUMBER: 35 // after a 1 second delay
46-
NEXT NUMBER: 40 // after a 1 second delay
47-
NEXT NUMBER: 45 // after a 1 second delay
48-
NEXT NUMBER: 50 // after a 1 second delay
49-
I AM COMPLETE // same time as previous line
50-
```
51-
5213
### There a few plugins that are available - each return a new Observable instance
5314

5415
- [Documentation on the plugin operators can be seen here](./src/operators/DOCUMENTATION.md)

example/adder.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// same example as https://github.com/cujojs/most#simple-example
22

3-
const { fromEvent, combineLatest } = Servable;
3+
const { fromEvent, combine } = Servable;
44

55
const xInput = document.querySelector('input.x');
66
const yInput = document.querySelector('input.y');
@@ -22,7 +22,7 @@ const main = () => {
2222
const y = fromEvent('input', yInput).map(toNumber);
2323

2424
// result is the live current value of adding x and y
25-
const result = combineLatest(x, y, add);
25+
const result = combine([x, y], add);
2626

2727
// Observe the result value by rendering it to the resultNode
2828
result.subscribe(renderResult);

example/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ <h3>Adder</h3>
1818
</form>
1919
</div>
2020

21-
<script type="text/javascript" src="../dist/index.min.js"></script>
21+
<script type="text/javascript" src="../dist/index.js"></script>
2222
<script type="text/javascript" src="index.js"></script>
2323
<script type="text/javascript" src="adder.js"></script>
2424
</body>

example/index.js

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
const { Observable } = Servable;
22

3-
const countObservable$ = Observable.interval(1000, 1);
4-
5-
const countSubscription = countObservable$
6-
.take(10)
7-
.map((n) => n * 5)
8-
.filter((n) => n > 10)
9-
.combineLatest(
10-
countObservable$
11-
.take(5)
12-
)
3+
const countObservable$ = Observable.interval(1000, 1).take(4);
4+
const countObservable2$ = Observable.interval(500, 5);
5+
6+
const countSubscription =
7+
Observable.zip([
8+
countObservable$,
9+
countObservable2$.take(7),
10+
countObservable$,
11+
countObservable2$.take(7),
12+
])
13+
// countObservable2$.take(5)
1314
.subscribe({
1415
next (number) {
1516
console.log('NEXT NUMBER: ', number);
@@ -20,7 +21,7 @@ const countSubscription = countObservable$
2021
},
2122

2223
complete () {
23-
console.log('I AM COMPLETE');
24+
console.trace('I AM COMPLETE');
2425
}
2526
});
2627

@@ -39,3 +40,13 @@ inputObservable$
3940
inputObservable$
4041
.do((text) => div.textContent = text)
4142
.subscribe();
43+
44+
Observable
45+
.ajax('../package.json')
46+
.do(console.log.bind(console.log, 'response'))
47+
.flatMap(response => Observable.fromPromise(response.json()))
48+
.do(console.log.bind(console.log, 'value'))
49+
.subscribe({
50+
next: (value) => console.log(value),
51+
error: (e) => console.warn(e, e.response)
52+
});

package.json

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
{
22
"name": "servable",
3-
"version": "0.3.1",
3+
"version": "0.3.2",
44
"description": "From scratch observable",
55
"main": "lib/index.js",
66
"jsnext:main": "src/index.js",
77
"scripts": {
88
"test": "echo \"Error: no test specified\" && exit 0",
99
"build": "rimraf lib dist && buba src -o lib && rollup -c && uglifyjs dist/index.js -c \"warnings=false\" --comments -m -o dist/index.min.js --verbose",
1010
"watch": "rollup -c -w",
11-
"release": "node release.js"
11+
"release": "node release.js",
12+
"server": "http-server"
1213
},
1314
"repository": {
1415
"type": "git",
@@ -22,13 +23,15 @@
2223
"homepage": "https://github.com/maniator/servable#readme",
2324
"devDependencies": {
2425
"buba": "^4.0.2",
26+
"http-server": "^0.10.0",
2527
"inquirer": "^3.0.6",
2628
"rimraf": "^2.6.1",
2729
"rollup": "^0.41.6",
2830
"rollup-plugin-buble": "^0.15.0",
31+
"rollup-plugin-filesize": "^1.3.2",
2932
"rollup-plugin-license": "^0.3.0",
33+
"rollup-plugin-node-globals": "^1.1.0",
3034
"rollup-plugin-node-resolve": "^3.0.0",
31-
"rollup-plugin-sizes": "^0.3.0",
3235
"rollup-watch": "^3.2.2",
3336
"semver": "^5.3.0",
3437
"shelljs": "^0.7.7",

rollup.config.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import buble from 'rollup-plugin-buble';
22
import nodeResolve from 'rollup-plugin-node-resolve';
3-
import sizes from 'rollup-plugin-sizes';
3+
import filesize from 'rollup-plugin-filesize';
44
import license from 'rollup-plugin-license';
5+
import globals from 'rollup-plugin-node-globals';
56

67
const pkg = require('./package.json');
78

@@ -18,7 +19,8 @@ export default {
1819
sourceMap: true,
1920
plugins: [
2021
buble(),
21-
sizes(),
22+
filesize(),
23+
globals(),
2224
license({
2325
banner,
2426
}),

src/Observer.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ export class Observer {
3636
use (callback) {
3737
return this.catchErrors(() => {
3838
const response = callback({
39-
next: (...args) => this.onNext(...args),
39+
next: (value) => this.onNext(value),
4040
error: (...errors) => this.onError(...errors),
4141
complete: () => this.onComplete(),
4242
});
@@ -57,9 +57,9 @@ export class Observer {
5757
return this.setupObserver(next);
5858
}
5959

60-
this.onNext = this.catchErrors((...args) => {
60+
this.onNext = this.catchErrors((value) => {
6161
if (!this.isComplete) {
62-
return next(...args);
62+
return next(value);
6363
}
6464
});
6565

src/Subject.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,9 @@ export class Subject {
4444
return this;
4545
}
4646

47-
next (...args) {
47+
next (value) {
4848
this.cleanup((observer) => {
49-
observer.onNext(...args);
49+
observer.onNext(value);
5050
});
5151
}
5252

src/observables.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
export * from './observables/ajax';
12
export * from './observables/fromEvent';
23
export * from './observables/fromPromise';
34
export * from './observables/range';

src/observables/DOCUMENTATION.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
These methods are called by doing: `Observable.<observableFunction>`
22

3+
`.ajax(url[, options])`
4+
5+
- an observable wrapper around the `fetch` API
6+
- you can add a shim like [this one](https://github.com/github/fetch) if your environment does not have the fetch api
7+
38
`.fromEvent(<eventName>, <element>[, <mapCallback>)`
49

510
- will create an observable that will listen for an event on a DOM element

src/observables/ajax.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { Observable } from '../Observable';
2+
import { fromPromise } from './fromPromise';
3+
4+
function checkStatus (response) {
5+
if (response.status >= 200 && response.status < 300) {
6+
return response;
7+
} else {
8+
var error = new Error(response.statusText);
9+
error.response = response;
10+
throw error;
11+
}
12+
}
13+
14+
// do an ajax call (depends on the "fetch" api existing)
15+
// can add this shim to simulate fetch in all browsers https://github.com/github/fetch
16+
export const ajax = function (...args) {
17+
return new Observable(function (observer) {
18+
if (global.fetch) {
19+
const fetchPromise = fetch(...args).then(checkStatus);
20+
const subscription = fromPromise(fetchPromise).subscribe(observer);
21+
22+
return () => subscription.unsubscribe();
23+
} else {
24+
throw new Error('Fetch API does not exist in your environment');
25+
}
26+
});
27+
};
28+
29+
Observable.ajax = ajax;

src/observables/fromPromise.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ import { isPromise } from '../utilities';
44
export const fromPromise = function (promise) {
55
return new Observable(function ({ next, complete, error }) {
66
if (isPromise(promise)) {
7-
promise.then(function (...values) {
8-
next(...values);
7+
promise.then(function (values) {
8+
next(values);
99
complete();
10-
}, error);
10+
}, error).catch(error);
1111
} else {
1212
error('Passed an invalid object to fromPromise', promise);
1313
}

src/operators.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@ export * from './operators/first';
88
export * from './operators/toPromise';
99
export * from './operators/flatMap';
1010
export * from './operators/switchMap';
11+
export * from './operators/merge';
1112
export * from './operators/scan';
1213
export * from './operators/reduce';
1314
export * from './operators/concat';
14-
export * from './operators/combineLatest';
15+
export * from './operators/zip';
16+
export * from './operators/combine';
1517
export * from './operators/count';
1618
export * from './operators/sum';
1719
export * from './operators/max';

src/operators/DOCUMENTATION.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
These methods called by doing: `observableInstance$.<pluginFunction>`
1+
These methods called by doing: `observableInstance$.<pluginFunction>` or by calling `Observable.<pluginFunction>(observableInstance$, ...arguments)`
22

33
`.map(<mapCallback>)`
44

@@ -75,7 +75,7 @@ These methods called by doing: `observableInstance$.<pluginFunction>`
7575

7676
- will run any number of observables in order and will only complete when the last one is done
7777

78-
`.combineLatest(otherSource$[, combineCallback])`
78+
`.combine(otherSources$[, combineCallback])`
7979

80-
- will run two observables at the same time
81-
- will only call the observer's next function when both observables have emitted at least one value
80+
- will multiple observables at the same time
81+
- will only call the observer's next function when all observables have emitted at least one value

src/operators/average.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export const average = function (source$) {
2121
});
2222
};
2323

24+
Observable.average = average;
2425
Observable.prototype.average = function () {
2526
return average(this);
2627
};

src/operators/combine.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { Observable } from '../Observable';
2+
import { onSubscriptionsComplete } from '../utilities/onSubscriptionsComplete';
3+
4+
const nullHash = void(0);
5+
6+
export const combine = function (sources$, combineCallback = ((...args) => [...args])) {
7+
return new Observable(function ({ next, error, complete }) {
8+
let subscriptions = [];
9+
10+
let latest = sources$.map(s$ => nullHash);
11+
12+
let allHasValue = false;
13+
const checkAllHasValue = () => latest.filter((l) => l == nullHash).length <= 0;
14+
15+
const onComplete = () => onSubscriptionsComplete(subscriptions, complete);
16+
const subscribeTo = (obs$, index) => {
17+
return obs$.subscribe({
18+
next (value) {
19+
latest[index] = value;
20+
21+
allHasValue = allHasValue || checkAllHasValue();
22+
23+
if (allHasValue) {
24+
next(combineCallback(...latest));
25+
}
26+
},
27+
error,
28+
complete: onComplete,
29+
});
30+
};
31+
32+
subscriptions = sources$.map((s$, index) => subscribeTo(s$, index));
33+
34+
return () => subscriptions.forEach((s) => s.unsubscribe());
35+
});
36+
};
37+
38+
Observable.combine = combine;
39+
Observable.prototype.combine = function (otherSources$, combineCallback) {
40+
return combine([this, ...otherSources$], combineCallback);
41+
};

src/operators/combineLatest.js

Lines changed: 0 additions & 46 deletions
This file was deleted.

0 commit comments

Comments
 (0)