/
bey.js
82 lines (71 loc) · 1.71 KB
/
bey.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
// @flow
'use strict';
const React = require('react');
const immer = require('immer').default;
const shallowEqual = require('fbjs/lib/shallowEqual');
function state(initialState) {
let listeners = [];
let currentState = initialState;
return {
get() {
return currentState;
},
set(nextState) {
currentState = nextState;
listeners.forEach(listener => listener());
},
on(listener) {
listeners.push(listener);
},
off(listener) {
listeners = listeners.filter(fn => fn !== listener);
},
reset() {
currentState = initialState;
},
};
}
function update(target, updater) {
let currState = target.get();
let nextState = immer(currState, updater);
if (nextState !== currState) target.set(nextState);
}
class Subscribe extends React.Component {
static defaultProps = {
on: state => state,
};
_shouldUpdate = false;
_state = this.getState();
componentDidMount() {
this._shouldUpdate = true;
this.props.to.on(this.onUpdate);
}
componentDidUpdate(prevProps) {
if (this.props.to !== prevProps.to) {
prevProps.to.off(this.onUpdate);
this.props.to.on(this.onUpdate);
}
}
componentWillUnmount() {
this._shouldUpdate = false;
this.props.to.off(this.onUpdate);
}
getState() {
return this.props.on(this.props.to.get());
}
onUpdate = () => {
let prevState = this._state;
let nextState = this.getState();
this._state = nextState;
if (!this._shouldUpdate) return;
if (!shallowEqual(nextState, prevState)) {
this.setState({});
}
};
render() {
return this.props.children(this._state);
}
}
exports.state = state;
exports.update = update;
exports.Subscribe = Subscribe;