From 46f812b17a2439814c6bc017edda2f383bb89663 Mon Sep 17 00:00:00 2001 From: Herrington Darkholme Date: Mon, 11 Sep 2017 23:57:38 +0800 Subject: [PATCH 1/5] typing file skeleton --- types/index.d.ts | 0 types/test/index.ts | 0 types/tsconfig.json | 16 ++++++++++++++++ types/typings.json | 4 ++++ 4 files changed, 20 insertions(+) create mode 100644 types/index.d.ts create mode 100644 types/test/index.ts create mode 100644 types/tsconfig.json create mode 100644 types/typings.json diff --git a/types/index.d.ts b/types/index.d.ts new file mode 100644 index 0000000..e69de29 diff --git a/types/test/index.ts b/types/test/index.ts new file mode 100644 index 0000000..e69de29 diff --git a/types/tsconfig.json b/types/tsconfig.json new file mode 100644 index 0000000..790fdba --- /dev/null +++ b/types/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "es5", + "lib": [ + "es5", + "dom", + "es2015.promise" + ], + "stict": true, + "noEmit": true + }, + "include": [ + "*.d.ts" + ] +} diff --git a/types/typings.json b/types/typings.json new file mode 100644 index 0000000..4f37001 --- /dev/null +++ b/types/typings.json @@ -0,0 +1,4 @@ +{ + "name": "vue-rx", + "main": "index.d.ts" +} From cf715ba39d94c9798030054089381c1eee0bdb19 Mon Sep 17 00:00:00 2001 From: Herrington Darkholme Date: Tue, 12 Sep 2017 00:16:06 +0800 Subject: [PATCH 2/5] add initial typing --- types/index.d.ts | 28 ++++++++++++++++++++++++++++ types/tsconfig.json | 2 +- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/types/index.d.ts b/types/index.d.ts index e69de29..97e8de1 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -0,0 +1,28 @@ +import Vue = require('vue') +import { WatchOptions } from 'vue' +import { Observable } from 'rxjs/Observable' + +export type Observables = Record> +declare module 'vue/types/options' { + interface ComponentOptions { + subscriptions: Observables | (() => Observables) + domStreams: string[] + } +} + +declare module "vue/types/vue" { + interface Vue { + $observables: Observables; + $watchAsObservable(exprOrFn: string | Function, options?: WatchOptions): Observable + $eventToObservable(event: string): Observable + $subscribeTo( + observable: Observable, + next: (t: T) => void, + error: (e: any) => void, + complete: () => void): void + $fromDOMEvent(selector: string, event: string): Observable + $createObservableMethod(methodName: string): Observable + } +} + +export declare function install(V: typeof Vue): void diff --git a/types/tsconfig.json b/types/tsconfig.json index 790fdba..8b72d79 100644 --- a/types/tsconfig.json +++ b/types/tsconfig.json @@ -7,7 +7,7 @@ "dom", "es2015.promise" ], - "stict": true, + "strict": true, "noEmit": true }, "include": [ From 0d328e1b1691d08eb6969c6c4b2356bb298e9759 Mon Sep 17 00:00:00 2001 From: Herrington Darkholme Date: Tue, 12 Sep 2017 00:50:36 +0800 Subject: [PATCH 3/5] add type tests --- types/index.d.ts | 4 +-- types/test/index.ts | 73 ++++++++++++++++++++++++++++++++++++++++ types/test/tsconfig.json | 14 ++++++++ 3 files changed, 89 insertions(+), 2 deletions(-) create mode 100644 types/test/tsconfig.json diff --git a/types/index.d.ts b/types/index.d.ts index 97e8de1..b20a2e5 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -5,8 +5,8 @@ import { Observable } from 'rxjs/Observable' export type Observables = Record> declare module 'vue/types/options' { interface ComponentOptions { - subscriptions: Observables | (() => Observables) - domStreams: string[] + subscriptions?: Observables | ((this: V) => Observables) + domStreams?: string[] } } diff --git a/types/test/index.ts b/types/test/index.ts index e69de29..98dde72 100644 --- a/types/test/index.ts +++ b/types/test/index.ts @@ -0,0 +1,73 @@ +import Vue = require('vue') +import * as VueRX from '../index' +import * as Rx from 'rxjs/Rx' + +Vue.use(VueRX, Rx) + +var vm = new Vue({ + el: '#app', + subscriptions: { + msg: Rx.Observable.interval(100) + } +}) + +vm.$observables.msg.subscribe(msg => console.log(msg)) + +Vue.component('foo', { + subscriptions: function () { + return { + msg: Rx.Observable.interval(100) + } + } +}) + +new Vue({ + domStreams: ['plus$'] +}) + +var vm = new Vue({ + data: { + a: 1 + }, + subscriptions () { + // declaratively map to another property with Rx operators + return { + aPlusOne: this.$watchAsObservable('a') + .pluck('newValue') + .map((a: number) => a + 1) + } + } +}) + +// or produce side effects... +vm.$watchAsObservable('a') + .subscribe( + ({ newValue, oldValue }) => console.log('stream value', newValue, oldValue), + err => console.error(err), + () => console.log('complete') + ) + + +var vm = new Vue({ + created () { + this.$eventToObservable('customEvent') + .subscribe((event) => console.log(event.name,event.msg)) + } +}) + +var vm = new Vue({ + subscriptions () { + return { + inputValue: this.$fromDOMEvent('input', 'keyup').pluck('target', 'value') + } + } +}) + +var vm = new Vue({ + subscriptions () { + return { + // requires `share` operator + formData: this.$createObservableMethod('submitHandler') + } + } +}) diff --git a/types/test/tsconfig.json b/types/test/tsconfig.json new file mode 100644 index 0000000..92c948e --- /dev/null +++ b/types/test/tsconfig.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "es5", + "lib": [ + "es5", + "dom", + "es2015.promise", + "es2015.core" + ], + "strict": true, + "noEmit": true + } +} From f4d2c0964d591199b91522f7b35eb53c8635f100 Mon Sep 17 00:00:00 2001 From: Herrington Darkholme Date: Tue, 12 Sep 2017 00:57:32 +0800 Subject: [PATCH 4/5] update package.json --- package-lock.json | 24 +++++++++++++++--------- package.json | 5 ++++- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2f5c26a..e0e1e25 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3325,15 +3325,6 @@ } } }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - }, "string-length": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/string-length/-/string-length-1.0.1.tgz", @@ -3354,6 +3345,15 @@ "strip-ansi": "3.0.1" } }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + }, "stringstream": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", @@ -3547,6 +3547,12 @@ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", "dev": true }, + "typescript": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.5.2.tgz", + "integrity": "sha1-A4qV99m7tCCxvzW6MdTFwd0//jQ=", + "dev": true + }, "uglify-js": { "version": "2.8.29", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", diff --git a/package.json b/package.json index 2124424..a9c3532 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,9 @@ "dev": "rollup -c rollup.config.js -w", "build": "rollup -c rollup.config.js", "lint": "eslint src test example --fix", - "test": "jest", + "test": "npm run test:unit && npm run test:types", + "test:unit": "jest", + "test:types": "tsc -p types/test", "dev:test": "jest --watch", "prebuild": "npm run lint", "pretest": "npm run build", @@ -41,6 +43,7 @@ "rollup-plugin-buble": "^0.15.0", "rollup-watch": "^3.2.2", "rxjs": "^5.2.0", + "typescript": "^2.5.2", "vue": "^2.2.4" }, "eslintConfig": { From 46e63c285d25041b738bdc854d5b7fa8a42bea1e Mon Sep 17 00:00:00 2001 From: Herrington Darkholme Date: Tue, 12 Sep 2017 20:59:45 +0800 Subject: [PATCH 5/5] address code review and improve types --- types/index.d.ts | 16 +++++++++++----- types/test/index.ts | 17 +++++++++++++++++ 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/types/index.d.ts b/types/index.d.ts index b20a2e5..75f09ca 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -7,20 +7,26 @@ declare module 'vue/types/options' { interface ComponentOptions { subscriptions?: Observables | ((this: V) => Observables) domStreams?: string[] + observableMethods?: string[] | Record } } +export interface WatchObservable { + newValue: T + oldValue: T +} declare module "vue/types/vue" { interface Vue { $observables: Observables; - $watchAsObservable(exprOrFn: string | Function, options?: WatchOptions): Observable - $eventToObservable(event: string): Observable + $watchAsObservable(expr: string, options?: WatchOptions): Observable> + $watchAsObservable(fn: (this: this) => T, options?: WatchOptions): Observable> + $eventToObservable(event: string): Observable<{name: string, msg: any}> $subscribeTo( observable: Observable, next: (t: T) => void, - error: (e: any) => void, - complete: () => void): void - $fromDOMEvent(selector: string, event: string): Observable + error?: (e: any) => void, + complete?: () => void): void + $fromDOMEvent(selector: string | null, event: string): Observable $createObservableMethod(methodName: string): Observable } } diff --git a/types/test/index.ts b/types/test/index.ts index 98dde72..ed6b91b 100644 --- a/types/test/index.ts +++ b/types/test/index.ts @@ -55,6 +55,14 @@ var vm = new Vue({ } }) +var vm = new Vue({ + mounted () { + this.$subscribeTo(Rx.Observable.interval(1000), function (count) { + console.log(count) + }) + } +}) + var vm = new Vue({ subscriptions () { return { @@ -71,3 +79,12 @@ var vm = new Vue({ } } }) + +var vm = new Vue({ + subscriptions () { + return { + // requires `share` operator + formData: this.$createObservableMethod('submitHandler') + } + } +})