├── .eslintrc ├── .gitignore ├── LICENSE ├── README.md ├── dist ├── RR.d.ts ├── RR.js └── test │ ├── test.d.ts │ └── test.js ├── lib ├── RR.ts ├── test │ └── test.ts └── tsconfig.json ├── package-lock.json └── package.json /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "rules": { 3 | "quotes": [ 4 | 2, 5 | "single" 6 | ], 7 | "linebreak-style": [ 8 | 2, 9 | "unix" 10 | ], 11 | "semi": [ 12 | 2, 13 | "always" 14 | ] 15 | }, 16 | "env": { 17 | "es6": true, 18 | "node": true, 19 | "browser": true 20 | }, 21 | "extends": "eslint:recommended", 22 | "ecmaFeatures": { 23 | "modules": true, 24 | "jsx": true, 25 | "experimentalObjectRestSpread": true 26 | }, 27 | "parser": "babel-eslint", 28 | "plugins": [ 29 | "react" 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Directory for instrumented libs generated by jscoverage/JSCover 11 | lib-cov 12 | 13 | # Coverage directory used by tools like istanbul 14 | coverage 15 | 16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 17 | .grunt 18 | 19 | # Compiled binary addons (http://nodejs.org/api/addons.html) 20 | build/Release 21 | 22 | # Dependency directory 23 | # Commenting this out is preferred by some people, see 24 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git- 25 | node_modules 26 | 27 | # Users Environment Variables 28 | .lock-wscript 29 | .DS_Store 30 | bundle.js 31 | bundle.min.js 32 | *.tsbuildinfo 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Wang Qiu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | RR - Reactive React 2 | =================== 3 | 4 | > A super tiny library to make React Component being real Reactive (based on [RxJS](https://github.com/Reactive-Extensions/RxJS)) 5 | -------------------------------------------------------------------------------- /dist/RR.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | /// 4 | /// 5 | /// 6 | /// 7 | /// 8 | /// 9 | /// 10 | import * as Rx from 'rx'; 11 | declare type ExtractObservableGenericType = T extends Rx.IObservable ? P : any; 12 | declare type ObservableTransFunc = (...args: Rx.Observable[]) => Rx.IObservable; 13 | declare type Action = { 14 | [key in keyof T]: Rx.Observable>; 15 | }; 16 | declare type ActionConfig = { 17 | [key in keyof T]: ObservableTransFunc>; 18 | }; 19 | interface IObservableStatic { 20 | createAction(config: ActionConfig): Action; 21 | createAction(names: string[], func: (...args: Rx.Observable[]) => Action): Action; 22 | bind(observableName: string, transform?: Function): (obj: T) => void; 23 | } 24 | declare const RR: { 25 | replicate(source: Rx.IObservable, name?: string): any; 26 | getObservable(name: string): Rx.ISubject; 27 | Observable: IObservableStatic; 28 | }; 29 | export = RR; 30 | -------------------------------------------------------------------------------- /dist/RR.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var Rx = require("rx"); 3 | var _observablePool = {}; 4 | function _replicate(source, subject) { 5 | return source.subscribe(function onOnNext(x) { 6 | setTimeout(function () { 7 | subject.onNext(x); 8 | }, 0); 9 | }, function onError(err) { 10 | subject.onError(err); 11 | }, function onComplete() { 12 | subject.onCompleted(); 13 | }); 14 | } 15 | function _getObservable(name) { 16 | return (_observablePool[name] = _observablePool[name] || new Rx.Subject()); 17 | } 18 | function _replicatedSubject(source) { 19 | return RR.replicate(source); 20 | } 21 | function getArgumentsNames(fn) { 22 | return fn 23 | .toString() 24 | .replace(/((\/\/.*$)|(\/\*[\s\S]*?\*\/)|(\s))/gm, '') 25 | .match(/^function\s*[^\(]*\(\s*([^\)]*)\)/m)[1] 26 | .split(/,/); 27 | } 28 | function argumentsAre(args, types) { 29 | return types 30 | .map(function (type, idx) { 31 | if (type == 'object') { 32 | return !!args[idx] && !('length' in args[idx]) && typeof args[idx] == 'object'; 33 | } 34 | else if (type == 'array') { 35 | return !!args[idx] && 'length' in args[idx]; 36 | } 37 | else if (type == 'function') { 38 | return !!args[idx] && typeof args[idx] == 'function'; 39 | } 40 | else { 41 | return !!args[idx]; 42 | } 43 | }) 44 | .reduce(function (sofar, curr) { 45 | return sofar && curr; 46 | }, true); 47 | } 48 | function defineMemorizedGetter(obj, name, getter) { 49 | var val; 50 | Object.defineProperty(obj, name, { 51 | get: function () { 52 | if (!val) { 53 | val = getter.call(obj); 54 | } 55 | return val; 56 | }, 57 | }); 58 | } 59 | function _assignReplicatedSubject(context) { 60 | return function (observable, prop) { 61 | return (context[prop] = _replicatedSubject(observable)); 62 | }; 63 | } 64 | var Observable = { 65 | createAction: function () { 66 | var args = []; 67 | for (var _i = 0; _i < arguments.length; _i++) { 68 | args[_i] = arguments[_i]; 69 | } 70 | var dependencies = [], register, extend; 71 | var action = {}; 72 | if (argumentsAre(args, ['object'])) { 73 | var config_1 = args[0]; 74 | action = Object.keys(config_1).reduce(function (ext, key) { 75 | defineMemorizedGetter(ext, key, function () { 76 | var deps = getArgumentsNames(config_1[key]).map(_getObservable); 77 | return _replicatedSubject(config_1[key].apply(ext, deps)); 78 | }); 79 | return ext; 80 | }, action); 81 | } 82 | else { 83 | if (argumentsAre(args, ['array', 'function'])) { 84 | dependencies = args[0]; 85 | register = args[1]; 86 | } 87 | else if (argumentsAre(args, ['function'])) { 88 | register = args[0]; 89 | dependencies = getArgumentsNames(register); 90 | } 91 | extend = register.apply(action, dependencies.map(_getObservable)); 92 | for (var prop in extend) { 93 | _assignReplicatedSubject(action)(extend[prop], prop); 94 | } 95 | } 96 | return action; 97 | }, 98 | bind: function (observableName, transform) { 99 | var subject = new Rx.Subject(), trans = transform || (function (x) { return x; }), context = null, disposable = null; 100 | return function (obj) { 101 | if (context !== this) { 102 | if (disposable) { 103 | disposable.dispose(); 104 | subject = new Rx.Subject(); 105 | } 106 | disposable = _replicate(trans.apply(this, [subject, this]), _getObservable(observableName)); 107 | context = this; 108 | } 109 | return subject.onNext(obj); 110 | }; 111 | }, 112 | }; 113 | var RR = { 114 | replicate: function (source, name) { 115 | if (name === void 0) { name = null; } 116 | var sub = name ? _getObservable(name) : new Rx.Subject(); 117 | var ret = Object.create(sub); 118 | Object.defineProperties(ret, { 119 | subject: { value: sub }, 120 | disposable: { value: _replicate(source, sub) }, 121 | }); 122 | return ret; 123 | }, 124 | getObservable: function (name) { 125 | return _getObservable(name); 126 | }, 127 | Observable: Observable, 128 | }; 129 | module.exports = RR; 130 | -------------------------------------------------------------------------------- /dist/test/test.d.ts: -------------------------------------------------------------------------------- 1 | export {}; 2 | -------------------------------------------------------------------------------- /dist/test/test.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | var Rx = require("rx"); 4 | var RR = require("../RR"); 5 | var action = RR.Observable.createAction({ 6 | a$: function () { 7 | return null; 8 | }, 9 | b$: function () { 10 | return null; 11 | }, 12 | }); 13 | action.a$.subscribe(function (item) { return item.length; }); 14 | var action2 = RR.Observable.createAction(['a$', 'b$'], function (a$, b$) { 15 | return { 16 | a$: new Rx.Subject(), 17 | b$: new Rx.Subject(), 18 | }; 19 | }); 20 | action2.b$.subscribe(function (p) { return p.x; }); 21 | var bindFunc = RR.Observable.bind('hello$', null); 22 | bindFunc('hello'); 23 | var Either = /** @class */ (function () { 24 | function Either(val) { 25 | this.val = val; 26 | } 27 | return Either; 28 | }()); 29 | var submitCourse = RR.Observable.bind('submitCourse$'); 30 | function handleFormSubmit(evt) { 31 | var formData = evt.formData; 32 | submitCourse(new Either(formData)); 33 | } 34 | var action3 = RR.Observable.createAction({ 35 | a$: function (submitCourse$) { 36 | submitCourse$.map(function (either) { return either.val.name; }); 37 | return null; 38 | }, 39 | b$: function () { 40 | return null; 41 | } 42 | }); 43 | action3.b$.subscribe(function (pos) { return console.log(pos.x); }); 44 | -------------------------------------------------------------------------------- /lib/RR.ts: -------------------------------------------------------------------------------- 1 | import * as Rx from 'rx'; 2 | 3 | type ExtractObservableGenericType = T extends Rx.IObservable ? P : any; 4 | type ObservableTransFunc = (...args: Rx.Observable[]) => Rx.IObservable; 5 | 6 | interface IObservablePool { 7 | [key: string]: Rx.ISubject; 8 | } 9 | 10 | type Action = { 11 | [key in keyof T]: Rx.Observable>; 12 | }; 13 | 14 | type ActionConfig = { 15 | [key in keyof T]: ObservableTransFunc>; 16 | }; 17 | 18 | interface IObservableStatic { 19 | createAction(config: ActionConfig): Action; 20 | // TODO: not well 21 | createAction(names: string[], func: (...args: Rx.Observable[]) => Action): Action; 22 | bind(observableName: string, transform?: Function): (obj: T) => void; 23 | } 24 | 25 | const _observablePool: IObservablePool = {}; 26 | 27 | function _replicate(source: Rx.IObservable, subject: Rx.Subject) { 28 | return source.subscribe( 29 | function onOnNext(x) { 30 | setTimeout(() => { 31 | subject.onNext(x); 32 | }, 0); 33 | }, 34 | function onError(err) { 35 | subject.onError(err); 36 | }, 37 | function onComplete() { 38 | subject.onCompleted(); 39 | } 40 | ); 41 | } 42 | 43 | function _getObservable(name) { 44 | return (_observablePool[name] = _observablePool[name] || new Rx.Subject()); 45 | } 46 | 47 | function _replicatedSubject(source) { 48 | return RR.replicate(source); 49 | } 50 | 51 | function getArgumentsNames(fn: Function): string[] { 52 | return fn 53 | .toString() 54 | .replace(/((\/\/.*$)|(\/\*[\s\S]*?\*\/)|(\s))/gm, '') 55 | .match(/^function\s*[^\(]*\(\s*([^\)]*)\)/m)[1] 56 | .split(/,/); 57 | } 58 | 59 | function argumentsAre(args: any[], types: ('object' | 'array' | 'function')[]) { 60 | return types 61 | .map(function (type, idx) { 62 | if (type == 'object') { 63 | return !!args[idx] && !('length' in args[idx]) && typeof args[idx] == 'object'; 64 | } else if (type == 'array') { 65 | return !!args[idx] && 'length' in args[idx]; 66 | } else if (type == 'function') { 67 | return !!args[idx] && typeof args[idx] == 'function'; 68 | } else { 69 | return !!args[idx]; 70 | } 71 | }) 72 | .reduce(function (sofar, curr) { 73 | return sofar && curr; 74 | }, true); 75 | } 76 | 77 | function defineMemorizedGetter(obj, name, getter) { 78 | var val; 79 | Object.defineProperty(obj, name, { 80 | get() { 81 | if (!val) { 82 | val = getter.call(obj); 83 | } 84 | return val; 85 | }, 86 | }); 87 | } 88 | 89 | function _assignReplicatedSubject(context) { 90 | return function (observable, prop) { 91 | return (context[prop] = _replicatedSubject(observable)); 92 | }; 93 | } 94 | 95 | const Observable: IObservableStatic = { 96 | createAction(...args): Action { 97 | let dependencies = [], 98 | register, 99 | extend; 100 | let action: any = {}; 101 | 102 | if (argumentsAre(args, ['object'])) { 103 | let config = args[0]; 104 | action = Object.keys(config).reduce(function (ext, key) { 105 | defineMemorizedGetter(ext, key, function () { 106 | var deps = getArgumentsNames(config[key]).map(_getObservable); 107 | return _replicatedSubject(config[key].apply(ext, deps)); 108 | }); 109 | return ext; 110 | }, action); 111 | } else { 112 | if (argumentsAre(args, ['array', 'function'])) { 113 | dependencies = args[0]; 114 | register = args[1]; 115 | } else if (argumentsAre(args, ['function'])) { 116 | register = args[0]; 117 | dependencies = getArgumentsNames(register); 118 | } 119 | 120 | extend = register.apply(action, dependencies.map(_getObservable)); 121 | 122 | for (let prop in extend) { 123 | _assignReplicatedSubject(action)(extend[prop], prop); 124 | } 125 | } 126 | 127 | return action; 128 | }, 129 | bind(observableName: string, transform?: Function) { 130 | var subject = new Rx.Subject(), 131 | trans = transform || ((x) => x), 132 | context = null, 133 | disposable = null; 134 | 135 | return function (obj: T) { 136 | if (context !== this) { 137 | if (disposable) { 138 | disposable.dispose(); 139 | subject = new Rx.Subject(); 140 | } 141 | disposable = _replicate(trans.apply(this, [subject, this]), _getObservable(observableName)); 142 | context = this; 143 | } 144 | 145 | return subject.onNext(obj); 146 | }; 147 | }, 148 | }; 149 | 150 | const RR = { 151 | replicate(source: Rx.IObservable, name: string = null) { 152 | var sub = name ? _getObservable(name) : new Rx.Subject(); 153 | 154 | var ret = Object.create(sub); 155 | 156 | Object.defineProperties(ret, { 157 | subject: { value: sub }, 158 | disposable: { value: _replicate(source, sub) }, 159 | }); 160 | 161 | return ret; 162 | }, 163 | 164 | getObservable(name: string): Rx.ISubject { 165 | return _getObservable(name); 166 | }, 167 | 168 | Observable, 169 | }; 170 | 171 | export = RR; 172 | -------------------------------------------------------------------------------- /lib/test/test.ts: -------------------------------------------------------------------------------- 1 | import * as Rx from 'rx'; 2 | import * as RR from '../RR'; 3 | 4 | interface Pos { 5 | x: number; 6 | y: number; 7 | } 8 | 9 | interface ILessonAction { 10 | a$: Rx.IObservable; 11 | b$: Rx.IObservable; 12 | } 13 | 14 | const action = RR.Observable.createAction({ 15 | a$() { 16 | return null; 17 | }, 18 | b$() { 19 | return null; 20 | }, 21 | }); 22 | 23 | action.a$.subscribe((item) => item.length); 24 | 25 | const action2 = RR.Observable.createAction(['a$', 'b$'], function (a$, b$) { 26 | return { 27 | a$: new Rx.Subject(), 28 | b$: new Rx.Subject(), 29 | }; 30 | }); 31 | 32 | action2.b$.subscribe(p => p.x); 33 | 34 | const bindFunc = RR.Observable.bind('hello$', null); 35 | bindFunc('hello'); 36 | 37 | class Either { 38 | val: T 39 | constructor(val: T) { 40 | this.val = val; 41 | } 42 | } 43 | 44 | interface CourseSubmitData { 45 | name: string; 46 | age: number; 47 | } 48 | 49 | const submitCourse = RR.Observable.bind>('submitCourse$'); 50 | 51 | function handleFormSubmit(evt) { 52 | const formData = evt.formData; 53 | submitCourse(new Either(formData)); 54 | } 55 | 56 | interface Course { 57 | name: string; 58 | } 59 | 60 | interface IAction3 { 61 | a$: Rx.IObservable; 62 | b$: Rx.IObservable; 63 | } 64 | 65 | const action3 = RR.Observable.createAction({ 66 | a$(submitCourse$) { 67 | submitCourse$.map(either => (either as Either).val.name); 68 | return null; 69 | }, 70 | 71 | b$() { 72 | return null; 73 | } 74 | }); 75 | 76 | action3.b$.subscribe(pos => console.log(pos.x)); 77 | 78 | 79 | -------------------------------------------------------------------------------- /lib/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "skipLibCheck": true, 4 | "declaration": true, 5 | "incremental": true, 6 | "module": "commonjs", 7 | "target": "es5", 8 | "noImplicitAny": false, 9 | "sourceMap": false, 10 | "resolveJsonModule": true, 11 | "outDir": "../dist" 12 | }, 13 | "include": ["./**/*"], 14 | "exclude": [] 15 | } -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "reactive-react", 3 | "version": "2.1.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@types/rx": { 8 | "version": "4.1.2", 9 | "resolved": "https://registry.npmjs.org/@types/rx/-/rx-4.1.2.tgz", 10 | "integrity": "sha512-1r8ZaT26Nigq7o4UBGl+aXB2UMFUIdLPP/8bLIP0x3d0pZL46ybKKjhWKaJQWIkLl5QCLD0nK3qTOO1QkwdFaA==", 11 | "dev": true, 12 | "requires": { 13 | "@types/rx-core": "*", 14 | "@types/rx-core-binding": "*", 15 | "@types/rx-lite": "*", 16 | "@types/rx-lite-aggregates": "*", 17 | "@types/rx-lite-async": "*", 18 | "@types/rx-lite-backpressure": "*", 19 | "@types/rx-lite-coincidence": "*", 20 | "@types/rx-lite-experimental": "*", 21 | "@types/rx-lite-joinpatterns": "*", 22 | "@types/rx-lite-testing": "*", 23 | "@types/rx-lite-time": "*", 24 | "@types/rx-lite-virtualtime": "*" 25 | } 26 | }, 27 | "@types/rx-core": { 28 | "version": "4.0.3", 29 | "resolved": "https://registry.npmjs.org/@types/rx-core/-/rx-core-4.0.3.tgz", 30 | "integrity": "sha1-CzNUsSOM7b4rdPYybxOdvHpZHWA=", 31 | "dev": true 32 | }, 33 | "@types/rx-core-binding": { 34 | "version": "4.0.4", 35 | "resolved": "https://registry.npmjs.org/@types/rx-core-binding/-/rx-core-binding-4.0.4.tgz", 36 | "integrity": "sha512-5pkfxnC4w810LqBPUwP5bg7SFR/USwhMSaAeZQQbEHeBp57pjKXRlXmqpMrLJB4y1oglR/c2502853uN0I+DAQ==", 37 | "dev": true, 38 | "requires": { 39 | "@types/rx-core": "*" 40 | } 41 | }, 42 | "@types/rx-lite": { 43 | "version": "4.0.6", 44 | "resolved": "https://registry.npmjs.org/@types/rx-lite/-/rx-lite-4.0.6.tgz", 45 | "integrity": "sha512-oYiDrFIcor9zDm0VDUca1UbROiMYBxMLMaM6qzz4ADAfOmA9r1dYEcAFH+2fsPI5BCCjPvV9pWC3X3flbrvs7w==", 46 | "dev": true, 47 | "requires": { 48 | "@types/rx-core": "*", 49 | "@types/rx-core-binding": "*" 50 | } 51 | }, 52 | "@types/rx-lite-aggregates": { 53 | "version": "4.0.3", 54 | "resolved": "https://registry.npmjs.org/@types/rx-lite-aggregates/-/rx-lite-aggregates-4.0.3.tgz", 55 | "integrity": "sha512-MAGDAHy8cRatm94FDduhJF+iNS5//jrZ/PIfm+QYw9OCeDgbymFHChM8YVIvN2zArwsRftKgE33QfRWvQk4DPg==", 56 | "dev": true, 57 | "requires": { 58 | "@types/rx-lite": "*" 59 | } 60 | }, 61 | "@types/rx-lite-async": { 62 | "version": "4.0.2", 63 | "resolved": "https://registry.npmjs.org/@types/rx-lite-async/-/rx-lite-async-4.0.2.tgz", 64 | "integrity": "sha512-vTEv5o8l6702ZwfAM5aOeVDfUwBSDOs+ARoGmWAKQ6LOInQ8J4/zjM7ov12fuTpktUKdMQjkeCp07Vd73mPkxw==", 65 | "dev": true, 66 | "requires": { 67 | "@types/rx-lite": "*" 68 | } 69 | }, 70 | "@types/rx-lite-backpressure": { 71 | "version": "4.0.3", 72 | "resolved": "https://registry.npmjs.org/@types/rx-lite-backpressure/-/rx-lite-backpressure-4.0.3.tgz", 73 | "integrity": "sha512-Y6aIeQCtNban5XSAF4B8dffhIKu6aAy/TXFlScHzSxh6ivfQBQw6UjxyEJxIOt3IT49YkS+siuayM2H/Q0cmgA==", 74 | "dev": true, 75 | "requires": { 76 | "@types/rx-lite": "*" 77 | } 78 | }, 79 | "@types/rx-lite-coincidence": { 80 | "version": "4.0.3", 81 | "resolved": "https://registry.npmjs.org/@types/rx-lite-coincidence/-/rx-lite-coincidence-4.0.3.tgz", 82 | "integrity": "sha512-1VNJqzE9gALUyMGypDXZZXzR0Tt7LC9DdAZQ3Ou/Q0MubNU35agVUNXKGHKpNTba+fr8GdIdkC26bRDqtCQBeQ==", 83 | "dev": true, 84 | "requires": { 85 | "@types/rx-lite": "*" 86 | } 87 | }, 88 | "@types/rx-lite-experimental": { 89 | "version": "4.0.1", 90 | "resolved": "https://registry.npmjs.org/@types/rx-lite-experimental/-/rx-lite-experimental-4.0.1.tgz", 91 | "integrity": "sha1-xTL1y98/LBXaFt7Ykw0bKYQCPL0=", 92 | "dev": true, 93 | "requires": { 94 | "@types/rx-lite": "*" 95 | } 96 | }, 97 | "@types/rx-lite-joinpatterns": { 98 | "version": "4.0.1", 99 | "resolved": "https://registry.npmjs.org/@types/rx-lite-joinpatterns/-/rx-lite-joinpatterns-4.0.1.tgz", 100 | "integrity": "sha1-9w/jcFGKhDLykVjMkv+1a05K/D4=", 101 | "dev": true, 102 | "requires": { 103 | "@types/rx-lite": "*" 104 | } 105 | }, 106 | "@types/rx-lite-testing": { 107 | "version": "4.0.1", 108 | "resolved": "https://registry.npmjs.org/@types/rx-lite-testing/-/rx-lite-testing-4.0.1.tgz", 109 | "integrity": "sha1-IbGdEfTf1v/vWp0WSOnIh5v+Iek=", 110 | "dev": true, 111 | "requires": { 112 | "@types/rx-lite-virtualtime": "*" 113 | } 114 | }, 115 | "@types/rx-lite-time": { 116 | "version": "4.0.3", 117 | "resolved": "https://registry.npmjs.org/@types/rx-lite-time/-/rx-lite-time-4.0.3.tgz", 118 | "integrity": "sha512-ukO5sPKDRwCGWRZRqPlaAU0SKVxmWwSjiOrLhoQDoWxZWg6vyB9XLEZViKOzIO6LnTIQBlk4UylYV0rnhJLxQw==", 119 | "dev": true, 120 | "requires": { 121 | "@types/rx-lite": "*" 122 | } 123 | }, 124 | "@types/rx-lite-virtualtime": { 125 | "version": "4.0.3", 126 | "resolved": "https://registry.npmjs.org/@types/rx-lite-virtualtime/-/rx-lite-virtualtime-4.0.3.tgz", 127 | "integrity": "sha512-3uC6sGmjpOKatZSVHI2xB1+dedgml669ZRvqxy+WqmGJDVusOdyxcKfyzjW0P3/GrCiN4nmRkLVMhPwHCc5QLg==", 128 | "dev": true, 129 | "requires": { 130 | "@types/rx-lite": "*" 131 | } 132 | }, 133 | "rx": { 134 | "version": "4.1.0", 135 | "resolved": "https://registry.npmjs.org/rx/-/rx-4.1.0.tgz", 136 | "integrity": "sha1-pfE/957zt0D+MKqAP7CfmIBdR4I=" 137 | }, 138 | "typescript": { 139 | "version": "4.1.2", 140 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.2.tgz", 141 | "integrity": "sha512-thGloWsGH3SOxv1SoY7QojKi0tc+8FnOmiarEGMbd/lar7QOEd3hvlx3Fp5y6FlDUGl9L+pd4n2e+oToGMmhRQ==", 142 | "dev": true 143 | } 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "reactive-react", 3 | "version": "3.0.7", 4 | "description": "RR - Reactive React. A super tiny but purely reactive implementation of Flux architecture.", 5 | "main": "./dist/RR.js", 6 | "types": "./dist/RR.d.ts", 7 | "scripts": { 8 | "watch": "tsc -w --listFiles -p lib --outDir dist", 9 | "build": "rm -rf dist && tsc --listFiles -p lib" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "https://github.com/winsonwq/RR.git" 14 | }, 15 | "keywords": [ 16 | "reactive", 17 | "react", 18 | "flux", 19 | "RxJS", 20 | "Observable" 21 | ], 22 | "author": "Wang Qiu (http://slender-man.github.io/)", 23 | "license": "MIT", 24 | "bugs": { 25 | "url": "https://github.com/winsonwq/RR/issues" 26 | }, 27 | "homepage": "https://github.com/winsonwq/RR", 28 | "dependencies": { 29 | "rx": "*" 30 | }, 31 | "browserify": { 32 | "transform": [ 33 | "browserify-shim" 34 | ] 35 | }, 36 | "browserify-shim": { 37 | "rx": "global:Rx" 38 | }, 39 | "devDependencies": { 40 | "@types/rx": "^4.1.2", 41 | "typescript": "^4.1.2" 42 | } 43 | } 44 | --------------------------------------------------------------------------------