Skip to content

Commit aa7ac5c

Browse files
committed
extract update and actions as machine
1 parent 3a1480e commit aa7ac5c

File tree

3 files changed

+43
-41
lines changed

3 files changed

+43
-41
lines changed

lib/__tests__/react-most-test.jsx

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,9 @@ describe('react-most', () => {
6464
</Most>
6565
)
6666
let counter = TestUtils.findRenderedComponentWithType(counterWrapper, Counter)
67-
counter.actions.inc()
68-
counter.actions.inc()
69-
counter.actions.inc()
67+
counter.machine.actions.inc()
68+
counter.machine.actions.inc()
69+
counter.machine.actions.inc()
7070
expect(stateHistoryOf(counter)[2].count).toBe(3)
7171
})
7272

@@ -77,9 +77,9 @@ describe('react-most', () => {
7777
</Most>
7878
)
7979
let counter = TestUtils.findRenderedComponentWithType(counterWrapper, Counter)
80-
counter.actions.inc();
81-
counter.actions.fromEvent({type:'inc'});
82-
return counter.actions.fromPromise(Promise.resolve({type:'inc'}))
80+
counter.machine.actions.inc();
81+
counter.machine.actions.fromEvent({type:'inc'});
82+
return counter.machine.actions.fromPromise(Promise.resolve({type:'inc'}))
8383
.then(()=>{
8484
expect(stateHistoryOf(counter)[2].count).toBe(3)
8585
})
@@ -94,7 +94,7 @@ describe('react-most', () => {
9494
)
9595
let counter = TestUtils.findRenderedComponentWithType(counterWrapper, Counter)
9696

97-
counter.actions.dec()
97+
counter.machine.actions.dec()
9898
expect(intentHistoryOf(counter)[1].type).toBe('dec triggered')
9999
})
100100

@@ -105,7 +105,7 @@ describe('react-most', () => {
105105
</Most>
106106
)
107107
let counter = TestUtils.findRenderedComponentWithType(counterWrapper, Counter)
108-
counter.actions.inc();
108+
counter.machine.actions.inc();
109109
expect(stateHistoryOf(counter)[0].count).toBe(10)
110110
})
111111

@@ -133,8 +133,8 @@ describe('react-most', () => {
133133
)
134134
let counterWrapper = TestUtils.findRenderedComponentWithType(counterMostWrapper, CounterWrapper)
135135
let counter = TestUtils.findRenderedComponentWithType(counterWrapper, Counter)
136-
counter.actions.changeWrapperProps('miao')
137-
counter.actions.changeDefaultProps(19)
136+
counter.machine.actions.changeWrapperProps('miao')
137+
counter.machine.actions.changeDefaultProps(19)
138138
let wrapperProps = TestUtils.findRenderedDOMComponentWithClass(counter, 'wrapperProps')
139139
let overwritedProps = TestUtils.findRenderedDOMComponentWithClass(counter, 'overwritedProps')
140140
let count = TestUtils.findRenderedDOMComponentWithClass(counter, 'count')
@@ -158,9 +158,9 @@ describe('react-most', () => {
158158
</Most>
159159
)
160160
let counter = TestUtils.findRenderedComponentWithType(counterWrapper, Counter)
161-
counter.actions.inc()
162-
counter.actions.inc()
163-
counter.actions.inc()
161+
counter.machine.actions.inc()
162+
counter.machine.actions.inc()
163+
counter.machine.actions.inc()
164164
let backward = TestUtils.findRenderedDOMComponentWithClass(counterWrapper, 'backward')
165165
TestUtils.Simulate.click(backward)
166166
TestUtils.Simulate.click(backward)
@@ -240,8 +240,8 @@ describe('react-most', () => {
240240
</Most>
241241
)
242242
let counter = TestUtils.findRenderedComponentWithType(counterWrapper, Counter)
243-
counter.actions.inc3()
244-
counter.actions.inc3()
243+
counter.machine.actions.inc3()
244+
counter.machine.actions.inc3()
245245
expect(stateHistoryOf(counter)[1].count).toBe(6)
246246
})
247247
})
@@ -288,7 +288,7 @@ describe('react-most', () => {
288288
)
289289
let counter = TestUtils.findRenderedComponentWithType(counterWrapper, Counter)
290290
expect(()=>{
291-
counter.actions.throwExeption()
291+
counter.machine.actions.throwExeption()
292292
}).toThrow('exception in reducer')
293293
})
294294
})

lib/interfaces.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
1-
import { Stream } from 'most'
1+
import { Stream, Subscription } from 'most'
22
import * as React from 'react'
33
import { AsyncSubject } from 'most-subject'
4-
4+
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?: {}): Process<I, S>
10+
(intent: EngineSubject<I>, props?: {}): Machine<I, S>
1111
}
1212
export interface Update<S> {
1313
(current: S): S
1414
}
15-
export interface Process<I, S> {
15+
export interface Machine<I, S> {
1616
actions: Actions<I>,
1717
update$: Stream<Update<S>>
1818
}
@@ -23,8 +23,9 @@ export interface ConnectProps<I> {
2323
}
2424

2525
export class Connect<I, S> extends React.PureComponent<ConnectProps<I>, S> {
26-
actions: Actions<I>
27-
update$: Stream<Update<S>>
26+
machine: Machine<I, S>
27+
traveler: Traveler<S>
28+
subscription: Subscription<S>
2829
}
2930

3031
export interface ConnectClass<I, S> {

lib/react-most.ts

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import * as React from 'react';
22
import { PropTypes } from 'prop-types';
33
import initHistory, { Traveler } from './history';
4-
import { Plan, Actions, Connect, ConnectProps, EngineSubject, Update, ConnectClass } from './interfaces'
5-
import { from, Stream, Subscription, mergeArray } from 'most';
4+
import { Plan, Connect, ConnectClass } from './interfaces'
5+
import { from, Stream, Subscription } from 'most';
66
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
@@ -12,30 +12,29 @@ const CONTEXT_TYPE = {
1212
[REACT_MOST_ENGINE]: PropTypes.object
1313
};
1414

15-
export function connect<I, S>(main: Plan<I, S>, opts = { history: false }): (WrappedComponent: React.ComponentClass<any>) => ConnectClass<I, S> {
16-
return function(WrappedComponent: ConnectClass<I, S>) {
15+
function isConnectClass<I, S>(ComponentClass: ConnectClass<I, S> | React.ComponentClass<any>): ComponentClass is ConnectClass<I, S> {
16+
return (<ConnectClass<I, S>>ComponentClass).contextTypes == CONTEXT_TYPE;
17+
}
18+
export type ConnectOrReactComponent<I, S> = ConnectClass<I, S> | React.ComponentClass<any>
19+
20+
export function connect<I, S>(main: Plan<I, S>, opts = { history: false }): (WrappedComponent: ConnectOrReactComponent<I, S>) => ConnectClass<I, S> {
21+
return function(WrappedComponent: ConnectOrReactComponent<I, S>) {
1722
let connectDisplayName = `Connect(${getDisplayName(WrappedComponent)})`;
18-
if (WrappedComponent.contextTypes === CONTEXT_TYPE) {
23+
if (isConnectClass(WrappedComponent)) {
1924
return class ConnectNode extends WrappedComponent {
20-
actions: Actions<I>
21-
update$: Stream<Update<S>>
22-
main: Plan<I, S>
2325
static contextTypes = CONTEXT_TYPE
2426
static displayName = connectDisplayName
2527
constructor(props, context) {
2628
super(props, context);
2729
let { actions, update$ } = main(context[REACT_MOST_ENGINE].intentStream, props)
28-
this.update$ = this.update$.merge(update$)
29-
this.actions = Object.assign({}, bindActions(actions, context[REACT_MOST_ENGINE].intentStream, this), this.actions);
30+
this.machine = {
31+
update$: this.machine.update$.merge(update$),
32+
actions: Object.assign({}, bindActions(actions, context[REACT_MOST_ENGINE].intentStream, this), this.machine.actions)
33+
}
3034
}
3135
}
3236
} else {
3337
return class ConnectLeaf extends Connect<I, S> {
34-
actions: Actions<I>
35-
update$: Stream<Update<S>>
36-
traveler: Traveler<S>
37-
subscription: Subscription<S>
38-
main: Plan<I, S>
3938
static contextTypes = CONTEXT_TYPE
4039
static displayName = connectDisplayName
4140
constructor(props, context) {
@@ -48,8 +47,10 @@ export function connect<I, S>(main: Plan<I, S>, opts = { history: false }): (Wra
4847
});
4948
}
5049
let { actions, update$ } = main(engine.intentStream, props)
51-
this.actions = bindActions(actions, engine.intentStream, this)
52-
this.update$ = update$
50+
this.machine = {
51+
actions: bindActions(actions, engine.intentStream, this),
52+
update$: update$
53+
}
5354
let defaultKey = Object.keys(WrappedComponent.defaultProps);
5455
this.state = Object.assign(
5556
{},
@@ -62,7 +63,7 @@ export function connect<I, S>(main: Plan<I, S>, opts = { history: false }): (Wra
6263
}
6364
componentDidMount() {
6465
this.subscription = this.context[REACT_MOST_ENGINE].observe(
65-
this.update$,
66+
this.machine.update$,
6667
action => {
6768
if (action instanceof Function) {
6869
this.setState((prevState, props) => {
@@ -91,7 +92,7 @@ export function connect<I, S>(main: Plan<I, S>, opts = { history: false }): (Wra
9192
return h(
9293
WrappedComponent,
9394
Object.assign({}, opts, this.props, this.state, {
94-
actions: this.actions,
95+
actions: this.machine.actions,
9596
traveler: this.traveler
9697
})
9798
);

0 commit comments

Comments
 (0)