From fb84e9687e6f175b7965d247ae6f4b358446d16f Mon Sep 17 00:00:00 2001 From: Tushar Mathur Date: Sat, 8 Oct 2016 19:00:22 +0530 Subject: [PATCH 1/6] chore(hooks): add ghooks --- package.json | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index c879a0b..5d75563 100644 --- a/package.json +++ b/package.json @@ -18,9 +18,12 @@ "benchmark": "^2.1.1", "cz-conventional-changelog": "^1.2.0", "es-observable-tests": "^0.3.0", + "ghooks": "^1.3.2", "semantic-release": "^4.3.5", + "tslint": "^3.15.1", "tslint-microsoft-contrib": "^2.0.12", - "typescript": "^2.0.3" + "typescript": "^2.0.3", + "validate-commit-msg": "^2.8.2" }, "repository": { "type": "git", @@ -29,6 +32,13 @@ "config": { "commitizen": { "path": "./node_modules/cz-conventional-changelog" + }, + "ghooks": { + "pre-commit": "npm run lint", + "commit-msg": "validate-commit-msg", + "pre-push": "npm test", + "post-merge": "npm install", + "post-rewrite": "npm install" } } } From ba0d2866190f215f2d410ebd344c7182d7caa895 Mon Sep 17 00:00:00 2001 From: Tushar Mathur Date: Sat, 8 Oct 2016 19:25:48 +0530 Subject: [PATCH 2/6] docs(readme): add file --- README.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..4834bca --- /dev/null +++ b/README.md @@ -0,0 +1,30 @@ +# Observable Air + +[![Build Status](https://travis-ci.org/tusharmath/rwc.svg?branch=master)](https://travis-ci.org/tusharmath/observable-air) +[![npm](https://img.shields.io/npm/v/observable-air.svg)](https://www.npmjs.com/package/observable-air) +[![Coverage Status](https://coveralls.io/repos/github/tusharmath/observable-air/badge.svg)](https://coveralls.io/github/tusharmath/observable-air) + +A light weight and performance focused implementation of [Observables]. +Other mainstream (no pun intended) alternatives — + +[Observables]: https://github.com/tc39/proposal-observable + +- [most] +- [rxjs] +- [kefir] +- [bacon] +- [highland] +- [zen observable] + +[most]: https://github.com/cujojs/most +[rxjs]: https://github.com/ReactiveX/rxjs +[kefir]: https://rpominov.github.io/kefir/ +[bacon]: https://baconjs.github.io/ +[highland]: http://highlandjs.org/ +[zen observable]: https://github.com/zenparsing/zen-observable + + ### Key Features + + 1. **Ultra high performance** + 2. **Small footprint** + 3. **Ease of testability** From fc374ae8d3a56f687610be90960dec732ff41fe3 Mon Sep 17 00:00:00 2001 From: Tushar Mathur Date: Sat, 8 Oct 2016 20:25:44 +0530 Subject: [PATCH 3/6] chore(package): add cleanup scripts --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 5d75563..c311c82 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,7 @@ "main": "src/Observable", "scripts": { "test": "ava", + "cleanup": "rm -rf ./src/**/*.js && rm -rf ./src/**/*.map", "lint": "tslint ./src/**.ts", "hydra": "node --trace-hydrogen --trace-phase=Z --trace-deopt --code-comments --hydrogen-track-positions --redirect-code-traces --redirect-code-traces-to=code.asm chore/benchmark.js", "rfc": "node chore/rfc", From fccce5d1ea6e81eda8e9f925abbfda44113d5ae4 Mon Sep 17 00:00:00 2001 From: Tushar Mathur Date: Sat, 8 Oct 2016 20:37:49 +0530 Subject: [PATCH 4/6] fix(SubscriptionObserver): handle more observer types observers could be of function type --- src/Observable.ts | 26 ++++++++++++---------- src/SubscriptionObserver.ts | 41 +++++++++++++++++++---------------- src/testing/TestObservable.ts | 2 +- 3 files changed, 38 insertions(+), 31 deletions(-) diff --git a/src/Observable.ts b/src/Observable.ts index 40c5ad7..4ee62cd 100644 --- a/src/Observable.ts +++ b/src/Observable.ts @@ -12,8 +12,15 @@ import {Subscription, CompositeSubscription} from './Subscription'; import {SubscriptionObserver} from './SubscriptionObserver'; import {SafeExecutor} from './lib/SafeExecutor'; import {Safety} from './types/ISafeValue'; +import {ISubscriptionObserver} from './types/core/ISubscriptionObserver'; +function startObserver (observer: IObserver, + subscription: CompositeSubscription) { + if (observer.start) + observer.start(subscription) +} + export class Observable implements IObservable { constructor (private func: ISubscriberFunction) { } @@ -27,21 +34,18 @@ export class Observable implements IObservable { }) } - safelyExecuteFunc (observer: IObserver, cSub: CompositeSubscription) { - const r = SafeExecutor(() => { - cSub.add(Subscription.from(this.func(SubscriptionObserver.from(observer)))) - }) - if (r.type === Safety.error && observer.error) { - observer.error(r.value as Error) - } + private safelyExecuteFunc (observer: ISubscriptionObserver, cSub: CompositeSubscription) { + const r = SafeExecutor(() => cSub.add(Subscription.from(this.func(observer)))) + if (r.type === Safety.error) observer.error(r.value as Error) } - subscribe (observer: IObserver, scheduler: IScheduler = new DefaultScheduler()): ISubscription { - if (typeof observer !== 'object') throw new TypeError('Observer should be of object type') + subscribe (observer: IObserver | ((t: T) => void), scheduler: IScheduler = new DefaultScheduler()): ISubscription { + const subObserver = SubscriptionObserver.from(observer) const subscription = new CompositeSubscription() - const task = () => this.safelyExecuteFunc(observer, subscription); + const task = () => this.safelyExecuteFunc(subObserver, subscription); subscription.add(scheduler.scheduleNow(task)) - if (observer.start) observer.start(subscription) + startObserver(observer as IObserver, subscription); return subscription } + } diff --git a/src/SubscriptionObserver.ts b/src/SubscriptionObserver.ts index 659724e..40ae5c3 100644 --- a/src/SubscriptionObserver.ts +++ b/src/SubscriptionObserver.ts @@ -5,42 +5,45 @@ import {ISubscriptionObserver} from './types/core/ISubscriptionObserver'; import {IObserver} from './types/core/IObserver'; -export class SubscriptionObserverStub implements ISubscriptionObserver { - closed: boolean; - - next (val: T): void { - } - - error (err: Error): void { - } - - complete (): void { - } +export function noop () { +} +export function defaultOnError (err: Error) { + throw err } + export class SubscriptionObserver implements ISubscriptionObserver { closed: boolean; - constructor (private sink: IObserver) { + constructor (private onNext: (val: T) => void, + private onError: (err: Error) => void, + private onComplete: () => void) { this.closed = false } next (val: T): void { - this.sink.next(val) + this.onNext(val) } error (err: Error): void { - this.sink.error(err) + this.onError(err) } complete (): void { - this.sink.complete() + this.onComplete() this.closed = true } - static from (observer: IObserver) { - if (!observer.next || !observer.complete || !observer.error) - return new SubscriptionObserverStub() - return new SubscriptionObserver(observer) + static from (observer: IObserver | ((t: T) => void)): ISubscriptionObserver { + const type = typeof observer + if (type !== 'object' && type !== 'function') throw new TypeError() + if (observer instanceof SubscriptionObserver) return observer + if (typeof observer === 'function') + return new SubscriptionObserver(observer, defaultOnError, noop) + return new SubscriptionObserver( + observer.next ? (t: T) => observer.next(t) : noop, + observer.error ? (t: Error) => observer.error(t) : defaultOnError, + observer.complete ? () => observer.complete() : noop + ) } } diff --git a/src/testing/TestObservable.ts b/src/testing/TestObservable.ts index faaee1d..43d10b3 100644 --- a/src/testing/TestObservable.ts +++ b/src/testing/TestObservable.ts @@ -16,6 +16,6 @@ export class TestObservable implements IObservable { } subscribe (observer: IObserver, scheduler: IScheduler): ISubscription { - return Subscription.from(this.func(new SubscriptionObserver(observer))) + return Subscription.from(this.func(SubscriptionObserver.from(observer))) } } From fc98ba6d04ba575572f6b185ad32653aa9853ed5 Mon Sep 17 00:00:00 2001 From: Tushar Mathur Date: Sat, 8 Oct 2016 20:41:29 +0530 Subject: [PATCH 5/6] chore(build): add coverall integration --- package.json | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index c311c82..594f4d6 100644 --- a/package.json +++ b/package.json @@ -3,20 +3,22 @@ "description": "Observables for the calorie conscious", "main": "src/Observable", "scripts": { - "test": "ava", + "benchmark": "date >> benchmark.md && node chore/benchmark >> benchmark.md", "cleanup": "rm -rf ./src/**/*.js && rm -rf ./src/**/*.map", - "lint": "tslint ./src/**.ts", + "coverage": "nyc npm test && nyc report --reporter=text-lcov | coveralls", "hydra": "node --trace-hydrogen --trace-phase=Z --trace-deopt --code-comments --hydrogen-track-positions --redirect-code-traces --redirect-code-traces-to=code.asm chore/benchmark.js", - "rfc": "node chore/rfc", - "benchmark": "date >> benchmark.md && node chore/benchmark >> benchmark.md", + "lint": "tslint ./src/**.ts", "postinstall": "tsc", - "semantic-release": "semantic-release pre && npm publish && semantic-release post" + "rfc": "node chore/rfc", + "semantic-release": "semantic-release pre && npm publish && semantic-release post", + "test": "ava" }, "author": "", "license": "ISC", "devDependencies": { "ava": "^0.16.0", "benchmark": "^2.1.1", + "coveralls": "^2.11.14", "cz-conventional-changelog": "^1.2.0", "es-observable-tests": "^0.3.0", "ghooks": "^1.3.2", From 462f6b0148bbdb53b0be18101d4340a7f06f44ce Mon Sep 17 00:00:00 2001 From: Tushar Mathur Date: Sat, 8 Oct 2016 20:47:46 +0530 Subject: [PATCH 6/6] chore(coverage): add nyc integration --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 594f4d6..94169ad 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "cz-conventional-changelog": "^1.2.0", "es-observable-tests": "^0.3.0", "ghooks": "^1.3.2", + "nyc": "^8.3.1", "semantic-release": "^4.3.5", "tslint": "^3.15.1", "tslint-microsoft-contrib": "^2.0.12",