Skip to content

Commit 4dc349e

Browse files
committed
rewrite rx engine as ts and change Subject API as default Subject.next
1 parent 1537e48 commit 4dc349e

15 files changed

+104
-91
lines changed

package.json

+5-4
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,14 @@
2323
"dependencies": {
2424
"most": "^1.2.2",
2525
"most-subject": "^5.2.0",
26-
"prop-types": "^15.5.8",
27-
"rxjs": "^5.0.0-rc.4"
26+
"prop-types": "^15.5.8"
2827
},
2928
"peerDependencies": {
30-
"react": "^15.5.4"
29+
"react": "^15.5.4",
30+
"@reactivex/rxjs": "^5.4.0"
3131
},
3232
"devDependencies": {
33+
"@reactivex/rxjs": "^5.4.0",
3334
"@types/jest": "^19.2.3",
3435
"@types/node": "^7.0.18",
3536
"@types/react": "^15.0.22",
@@ -38,7 +39,7 @@
3839
"react": "^15.5.4",
3940
"react-addons-test-utils": "^15.2.0",
4041
"react-dom": "^15.5.4",
41-
"react-most-spec": "^1.0.0",
42+
"react-most-spec": "^1.1.0",
4243
"redux": "^3.0.4",
4344
"ts-jest": "^20.0.2",
4445
"typescript": "^2.3.2"

src/__tests__/react-most-test.tsx

+8-8
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import * as TestUtils from 'react-addons-test-utils';
44
import * as most from 'most';
55

66
import Most, { connect, REACT_MOST_ENGINE } from '../../src/react-most';
7-
import { EngineSubject } from '../../src/interfaces'
7+
import { Subject } from 'most-subject'
88
import {
99
stateStreamOf, stateHistoryOf,
1010
intentStreamOf, intentHistoryOf,
@@ -32,14 +32,14 @@ interface Intent {
3232
type: string
3333
value?: any
3434
}
35-
const counterWrapper = connect((intent$: EngineSubject<Intent>) => {
35+
const counterWrapper = connect((intent$: Subject<Intent>) => {
3636
return {
3737
update$: intent$.map((intent: Intent) => {
3838
switch (intent.type) {
3939
case 'inc':
4040
return state => ({ count: state.count + 1 })
4141
case 'dec':
42-
intent$.send({ type: 'dec triggered' })
42+
intent$.next({ type: 'dec triggered' })
4343
return state => ({ count: state.count - 1 })
4444
case 'changeWrapperProps':
4545
return state => ({
@@ -188,7 +188,7 @@ describe('react-most', () => {
188188
})
189189

190190
describe('composable', () => {
191-
const counterWrapper2 = connect((intent$: EngineSubject<Intent>) => {
191+
const counterWrapper2 = connect((intent$: Subject<Intent>) => {
192192
return {
193193
update$: intent$.map(intent => {
194194
switch (intent.type) {
@@ -225,7 +225,7 @@ describe('react-most', () => {
225225
})
226226

227227
describe('convension default to `action` field in sinks', () => {
228-
const Counter = connect((intent$: EngineSubject<Intent>) => {
228+
const Counter = connect((intent$: Subject<Intent>) => {
229229
return {
230230
update$: intent$.map(intent => {
231231
switch (intent.type) {
@@ -255,7 +255,7 @@ describe('react-most', () => {
255255
})
256256

257257
describe('ERROR', () => {
258-
const Counter = connect((intent$: EngineSubject<Intent>) => {
258+
const Counter = connect((intent$: Subject<Intent>) => {
259259
return {
260260
update$: intent$.map(intent => {
261261
switch (intent.type) {
@@ -303,9 +303,9 @@ describe('react-most', () => {
303303

304304
describe('unsubscribe when component unmounted', () => {
305305
it('unsubscribe', (done) => {
306-
const Counter = connect((intent$: EngineSubject<Intent>) => {
306+
const Counter = connect((intent$: Subject<Intent>) => {
307307
let incForever$ = most.periodic(100, { type: 'inc' }).map(intent => {
308-
done.fail('should not send intent any more')
308+
done.fail('should not next intent any more')
309309
return _ => _
310310
})
311311
return {

src/engine/most.ts

+9-12
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
11
import { from, of, mergeArray, Stream, never, Subscription } from 'most'
2-
import { async as subject, AsyncSubject } from 'most-subject'
3-
import { EngineSubject, Update } from '../interfaces'
4-
export class Engine<T, S> {
5-
intentStream: EngineSubject<T>
6-
historyStream: EngineSubject<S>
7-
travelStream: EngineSubject<(n: number) => number>
2+
import { async as subject, AsyncSubject, Subject } from 'most-subject'
3+
import { Update } from '../interfaces'
4+
export default class Engine<T, S> {
5+
intentStream: Subject<T>
6+
historyStream: Subject<S>
7+
travelStream: Subject<(n: number) => number>
88
constructor() {
9-
this.intentStream = subject() as EngineSubject<T>
10-
this.intentStream.send = this.intentStream.next.bind(this.intentStream)
11-
this.historyStream = subject() as EngineSubject<S>
12-
this.historyStream.send = this.historyStream.next.bind(this.historyStream)
13-
this.travelStream = subject() as EngineSubject<(n: number) => number>;
14-
this.travelStream.send = this.travelStream.next.bind(this.historyStream)
9+
this.intentStream = subject() as Subject<T>
10+
this.historyStream = subject() as Subject<S>
11+
this.travelStream = subject() as Subject<(n: number) => number>;
1512
}
1613

1714
observe<T>(actionsSinks: Stream<Update<T>>, f): Subscription<T> {

src/engine/rx.js

-22
This file was deleted.

src/engine/rx.ts

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { Subject } from '@reactivex/rxjs/src/Subject'
2+
import { Observable } from '@reactivex/rxjs/src/Observable'
3+
import { Subscription } from '@reactivex/rxjs/src/Subscription'
4+
import 'rxjs/add/operator/map'
5+
import 'rxjs/add/operator/take'
6+
import 'rxjs/add/observable/from'
7+
import 'rxjs/add/operator/mergeAll'
8+
import { Update } from '../interfaces'
9+
10+
export default class Engine<T, S> {
11+
intentStream: Subject<T>
12+
historyStream: Subject<S>
13+
travelStream: Subject<(n: number) => number>
14+
constructor() {
15+
this.intentStream = new Subject()
16+
this.historyStream = new Subject()
17+
this.travelStream = new Subject()
18+
}
19+
20+
observe(actionsSinks: Observable<Update<T>>, f): Subscription {
21+
return actionsSinks.subscribe(
22+
f,
23+
(e) => console.error('Something is Wrong:', e, e.stack)
24+
)
25+
}
26+
}

src/history.ts

+7-6
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import { from, Stream } from 'most'
2-
import { Stamp, EngineSubject } from './interfaces'
2+
import { Subject } from 'most-subject'
3+
import { Stamp } from './interfaces'
34
export class Traveler<S> {
45
cursor: number
5-
path: EngineSubject<(n: number) => number>
6+
path: Subject<(n: number) => number>
67
history: Stream<Stamp<S>[]>
78
travel: Stream<S>
8-
constructor(history: Stream<Stamp<S>[]>, path: EngineSubject<(n: number) => number>) {
9+
constructor(history: Stream<Stamp<S>[]>, path: Subject<(n: number) => number>) {
910
this.history = history
1011
this.path = path
1112
this.travel = from(this.path)
@@ -19,15 +20,15 @@ export class Traveler<S> {
1920
.filter(x => !!x)
2021
}
2122
forward() {
22-
this.path.send(x => x + 1)
23+
this.path.next(x => x + 1)
2324
}
2425
backward() {
25-
this.path.send(x => x - 1)
26+
this.path.next(x => x - 1)
2627
}
2728

2829

2930
}
30-
export default function initHistory<S>(engineHistory: EngineSubject<S>, engineTravel: EngineSubject<(n: number) => number>): Traveler<S> {
31+
export default function initHistory<S>(engineHistory: Subject<S>, engineTravel: Subject<(n: number) => number>): Traveler<S> {
3132
let history = from(engineHistory)
3233
.timestamp()
3334
.scan((acc: Stamp<S>[], state: Stamp<S>) => {

src/interfaces.ts

+3-7
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import { Stream, Subscription } from 'most'
22
import * as React from 'react'
3-
import { AsyncSubject } from 'most-subject'
3+
import { Subject } from 'most-subject'
44
import { Traveler } from './history'
55
export interface Actions<T> {
66
[propName: string]: (...v: any[]) => T
77
}
88

99
export interface Plan<I, S> {
10-
(intent: EngineSubject<I>, props?: {}): Machine<I, S>
10+
(intent: Subject<I>, props?: {}): Machine<I, S>
1111
}
1212
export interface Update<S> {
1313
(current: S): S
@@ -36,15 +36,11 @@ export interface ConnectClass<I, S> {
3636
}
3737

3838
export interface History<S> {
39-
path: EngineSubject<(n: number) => number>
39+
path: Subject<(n: number) => number>
4040
history: Stream<S>
4141
}
4242

4343
export interface Stamp<S> {
4444
value: S
4545
time: number
4646
}
47-
48-
export interface EngineSubject<T> extends AsyncSubject<T> {
49-
send(x: T): this
50-
}

src/react-most.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { PropTypes } from 'prop-types';
33
import initHistory, { Traveler } from './history';
44
import { Plan, Connect, ConnectClass } from './interfaces'
55
import { from, Stream, Subscription } from 'most';
6-
import { Engine } from './engine/most';
6+
import Engine from './engine/most';
77

88
// unfortunately React doesn't support symbol as context key yet, so let me just preteding using Symbol until react implement the Symbol version of Object.assign
99
export const REACT_MOST_ENGINE = '@@reactive-react/react-most.engine';
@@ -70,7 +70,7 @@ export function connect<I, S>(main: Plan<I, S>, opts = { history: false }): (Wra
7070
let newState = action.call(this, prevState, props);
7171
if ((opts.history || props.history) && newState != prevState) {
7272
this.traveler.cursor = -1;
73-
this.context[REACT_MOST_ENGINE].historyStream.send(prevState);
73+
this.context[REACT_MOST_ENGINE].historyStream.next(prevState);
7474
}
7575
return newState;
7676
});
@@ -141,16 +141,16 @@ function inspect(engine) {
141141
function bindActions(actions, intent$, self) {
142142
let _actions = {
143143
fromEvent(e, f = x => x) {
144-
return intent$.send(f(e));
144+
return intent$.next(f(e));
145145
},
146146
fromPromise(p) {
147-
return p.then(x => intent$.send(x));
147+
return p.then(x => intent$.next(x));
148148
},
149149
};
150150

151151
for (let a in actions) {
152152
_actions[a] = (...args) => {
153-
return intent$.send(actions[a].apply(self, args));
153+
return intent$.next(actions[a].apply(self, args));
154154
};
155155
}
156156
return _actions;

tsconfig.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"include": [
3-
"src/*.ts"
3+
"src/**/*.ts"
44
],
55
"compilerOptions": {
66
"module": "commonjs",

types/engine/most.d.ts

+6-5
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import { Stream, Subscription } from 'most';
2-
import { EngineSubject, Update } from '../interfaces';
3-
export declare class Engine<T, S> {
4-
intentStream: EngineSubject<T>;
5-
historyStream: EngineSubject<S>;
6-
travelStream: EngineSubject<(n: number) => number>;
2+
import { Subject } from 'most-subject';
3+
import { Update } from '../interfaces';
4+
export default class Engine<T, S> {
5+
intentStream: Subject<T>;
6+
historyStream: Subject<S>;
7+
travelStream: Subject<(n: number) => number>;
78
constructor();
89
observe<T>(actionsSinks: Stream<Update<T>>, f: any): Subscription<T>;
910
}

types/engine/rx.d.ts

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { Subject } from '@reactivex/rxjs/src/Subject';
2+
import { Observable } from '@reactivex/rxjs/src/Observable';
3+
import { Subscription } from '@reactivex/rxjs/src/Subscription';
4+
import 'rxjs/add/operator/map';
5+
import 'rxjs/add/operator/take';
6+
import 'rxjs/add/observable/from';
7+
import 'rxjs/add/operator/mergeAll';
8+
import { Update } from '../interfaces';
9+
export default class Engine<T, S> {
10+
intentStream: Subject<T>;
11+
historyStream: Subject<S>;
12+
travelStream: Subject<(n: number) => number>;
13+
constructor();
14+
observe(actionsSinks: Observable<Update<T>>, f: any): Subscription;
15+
}

types/history.d.ts

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import { Stream } from 'most';
2-
import { Stamp, EngineSubject } from './interfaces';
2+
import { Subject } from 'most-subject';
3+
import { Stamp } from './interfaces';
34
export declare class Traveler<S> {
45
cursor: number;
5-
path: EngineSubject<(n: number) => number>;
6+
path: Subject<(n: number) => number>;
67
history: Stream<Stamp<S>[]>;
78
travel: Stream<S>;
8-
constructor(history: Stream<Stamp<S>[]>, path: EngineSubject<(n: number) => number>);
9+
constructor(history: Stream<Stamp<S>[]>, path: Subject<(n: number) => number>);
910
forward(): void;
1011
backward(): void;
1112
}
12-
export default function initHistory<S>(engineHistory: EngineSubject<S>, engineTravel: EngineSubject<(n: number) => number>): Traveler<S>;
13+
export default function initHistory<S>(engineHistory: Subject<S>, engineTravel: Subject<(n: number) => number>): Traveler<S>;

types/interfaces.d.ts

+4-7
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
/// <reference types="react" />
22
import { Stream, Subscription } from 'most';
33
import * as React from 'react';
4-
import { AsyncSubject } from 'most-subject';
4+
import { Subject } from 'most-subject';
55
import { Traveler } from './history';
66
export interface Actions<T> {
77
[propName: string]: (...v: any[]) => T;
88
}
99
export interface Plan<I, S> {
10-
(intent: EngineSubject<I>, props?: {}): Machine<I, S>;
10+
(intent: Subject<I>, props?: {}): Machine<I, S>;
1111
}
1212
export interface Update<S> {
1313
(current: S): S;
1414
}
1515
export interface Machine<I, S> {
1616
actions?: Actions<I>;
17-
update$?: Stream<Update<S>>;
17+
update$: Stream<Update<S>>;
1818
}
1919
export interface ConnectProps<I> {
2020
actions?: Actions<I>;
@@ -32,13 +32,10 @@ export interface ConnectClass<I, S> {
3232
new (props?: ConnectProps<I>, context?: any): Connect<I, S>;
3333
}
3434
export interface History<S> {
35-
path: EngineSubject<(n: number) => number>;
35+
path: Subject<(n: number) => number>;
3636
history: Stream<S>;
3737
}
3838
export interface Stamp<S> {
3939
value: S;
4040
time: number;
4141
}
42-
export interface EngineSubject<T> extends AsyncSubject<T> {
43-
send(x: T): this;
44-
}

types/react-most.d.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/// <reference types="react" />
22
import * as React from 'react';
33
import { Plan, ConnectClass } from './interfaces';
4-
import { Engine } from './engine/most';
4+
import Engine from './engine/most';
55
export declare const REACT_MOST_ENGINE = "@@reactive-react/react-most.engine";
66
export declare type ConnectOrReactComponent<I, S> = ConnectClass<I, S> | React.ComponentClass<any>;
77
export declare function connect<I, S>(main: Plan<I, S>, opts?: {

0 commit comments

Comments
 (0)