-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.js
127 lines (112 loc) · 3.17 KB
/
index.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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/* globals define */
(function (root, factory) {
"use strict";
if (typeof define === "function" && define.amd) {
define([], factory);
} else if (typeof exports === "object") {
module.exports = factory();
} else {
root.atom = factory();
}
})(this, function () {
"use strict";
return function (reducers, initialState) {
if (typeof reducers === "function") {
reducers = [reducers];
}
var listeners = [];
var state = initialState;
reducers.push(function setStateReducer(action, state) {
return action && action.type === "__ATOM_SET_STATE__"
? Object.assign(state, action.payload)
: state;
});
return {
addReducer: addReducer,
removeReducer: removeReducer,
dispatch: dispatch,
subscribe: subscribe,
unsubscribe: unsubscribe,
getState: getState,
setState: setState,
};
function addReducer(reducer) {
if (typeof reducer !== "function") {
throw new E("reducer must be a function");
}
reducers.push(reducer);
}
function removeReducer(reducer) {
if (!reducer) return;
const idx = reducers.findIndex((l) => l === reducer);
idx > -1 && reducers.splice(idx, 1);
}
function dispatch(/* action[, action1, action2, ...] */) {
var len = arguments.length;
var newState = getState();
for (var x = 0; x < len; x++) {
newState = callReducers(reducers, arguments[x], newState);
}
if (validState(newState)) {
cb(newState);
}
}
function subscribe(listener) {
if (typeof listener !== "function") {
throw new E("listener must be a function");
}
listeners.push(listener);
return function () {
unsubscribe(listener);
};
}
function unsubscribe(listener) {
if (!listener) return;
const idx = listeners.findIndex((l) => l === listener);
idx > -1 && listeners.splice(idx, 1);
}
function getState() {
return typeof state === "object" ? Object.assign({}, state) : state;
}
function setState(newState, meta) {
dispatch({ type: "__ATOM_SET_STATE__", payload: newState, meta: meta });
}
// Private
function callReducers(fns, action, state) {
var newState = state;
var len = reducers.length;
var ret;
for (var x = 0; x < len; x++) {
ret = fns[x](action, newState);
if (validState(ret)) {
newState = ret;
}
}
return newState;
}
function cb(newState) {
state = newState;
for (var x = 0; x < listeners.length; x++) {
listeners[x]();
}
}
function validState(newState) {
if (newState === undefined) {
throw new E("Reducer must return a value.");
} else if (typeof newState.then === "function") {
throw new E("Reducer cannot return a Promise.");
} else if (typeof newState === "function") {
newState(dispatch);
} else {
return true;
}
}
function E(message) {
this.message = message;
this.name = "AtomException";
this.toString = function () {
return this.name + ": " + this.message;
};
}
};
});