StateUtils.js
5.13 KB
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _invariant = require('./utils/invariant');
var _invariant2 = _interopRequireDefault(_invariant);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Utilities to perform atomic operation with navigate state and routes.
*
* ```javascript
* const state1 = {key: 'screen 1'};
* const state2 = NavigationStateUtils.push(state1, {key: 'screen 2'});
* ```
*/
var StateUtils = {
/**
* Gets a route by key. If the route isn't found, returns `null`.
*/
get: function get(state, key) {
return state.routes.find(function (route) {
return route.key === key;
}) || null;
},
/**
* Returns the first index at which a given route's key can be found in the
* routes of the navigation state, or -1 if it is not present.
*/
indexOf: function indexOf(state, key) {
return state.routes.map(function (route) {
return route.key;
}).indexOf(key);
},
/**
* Returns `true` at which a given route's key can be found in the
* routes of the navigation state.
*/
has: function has(state, key) {
return !!state.routes.some(function (route) {
return route.key === key;
});
},
/**
* Pushes a new route into the navigation state.
* Note that this moves the index to the positon to where the last route in the
* stack is at.
*/
push: function push(state, route) {
(0, _invariant2.default)(StateUtils.indexOf(state, route.key) === -1, 'should not push route with duplicated key %s', route.key);
var routes = state.routes.slice();
routes.push(route);
return _extends({}, state, {
index: routes.length - 1,
routes: routes
});
},
/**
* Pops out a route from the navigation state.
* Note that this moves the index to the positon to where the last route in the
* stack is at.
*/
pop: function pop(state) {
if (state.index <= 0) {
// [Note]: Over-popping does not throw error. Instead, it will be no-op.
return state;
}
var routes = state.routes.slice(0, -1);
return _extends({}, state, {
index: routes.length - 1,
routes: routes
});
},
/**
* Sets the focused route of the navigation state by index.
*/
jumpToIndex: function jumpToIndex(state, index) {
if (index === state.index) {
return state;
}
(0, _invariant2.default)(!!state.routes[index], 'invalid index %s to jump to', index);
return _extends({}, state, {
index: index
});
},
/**
* Sets the focused route of the navigation state by key.
*/
jumpTo: function jumpTo(state, key) {
var index = StateUtils.indexOf(state, key);
return StateUtils.jumpToIndex(state, index);
},
/**
* Sets the focused route to the previous route.
*/
back: function back(state) {
var index = state.index - 1;
var route = state.routes[index];
return route ? StateUtils.jumpToIndex(state, index) : state;
},
/**
* Sets the focused route to the next route.
*/
forward: function forward(state) {
var index = state.index + 1;
var route = state.routes[index];
return route ? StateUtils.jumpToIndex(state, index) : state;
},
/**
* Replace a route by a key.
* Note that this moves the index to the positon to where the new route in the
* stack is at.
*/
replaceAt: function replaceAt(state, key, route) {
var index = StateUtils.indexOf(state, key);
return StateUtils.replaceAtIndex(state, index, route);
},
/**
* Replace a route by a index.
* Note that this moves the index to the positon to where the new route in the
* stack is at.
*/
replaceAtIndex: function replaceAtIndex(state, index, route) {
(0, _invariant2.default)(!!state.routes[index], 'invalid index %s for replacing route %s', index, route.key);
if (state.routes[index] === route) {
return state;
}
var routes = state.routes.slice();
routes[index] = route;
return _extends({}, state, {
index: index,
routes: routes
});
},
/**
* Resets all routes.
* Note that this moves the index to the positon to where the last route in the
* stack is at if the param `index` isn't provided.
*/
reset: function reset(state, routes, index) {
(0, _invariant2.default)(routes.length && Array.isArray(routes), 'invalid routes to replace');
var nextIndex = index === undefined ? routes.length - 1 : index;
if (state.routes.length === routes.length && state.index === nextIndex) {
var compare = function compare(route, ii) {
return routes[ii] === route;
};
if (state.routes.every(compare)) {
return state;
}
}
(0, _invariant2.default)(!!routes[nextIndex], 'invalid index %s to reset', nextIndex);
return _extends({}, state, {
index: nextIndex,
routes: routes
});
}
};
exports.default = StateUtils;