UNPKG

3.53 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.routeReducer = routeReducer;
7exports.syncHistory = syncHistory;
8// Constants
9
10var TRANSITION = exports.TRANSITION = '@@router/TRANSITION';
11var UPDATE_LOCATION = exports.UPDATE_LOCATION = '@@router/UPDATE_LOCATION';
12
13var SELECT_STATE = function SELECT_STATE(state) {
14 return state.routing;
15};
16
17function transition(method) {
18 return function (arg) {
19 return {
20 type: TRANSITION,
21 method: method, arg: arg
22 };
23 };
24}
25
26var routeActions = exports.routeActions = {
27 push: transition('push'),
28 replace: transition('replace'),
29 go: transition('go'),
30 goBack: transition('goBack'),
31 goForward: transition('goForward')
32};
33
34function updateLocation(location) {
35 return {
36 type: UPDATE_LOCATION,
37 location: location
38 };
39}
40
41// Reducer
42
43var initialState = {
44 location: undefined
45};
46
47function routeReducer() {
48 var state = arguments.length <= 0 || arguments[0] === undefined ? initialState : arguments[0];
49 var _ref = arguments[1];
50 var type = _ref.type;
51 var location = _ref.location;
52
53 if (type !== UPDATE_LOCATION) {
54 return state;
55 }
56
57 return { location: location };
58}
59
60// Syncing
61
62function syncHistory(history) {
63 var unsubscribeHistory = undefined,
64 currentKey = undefined,
65 unsubscribeStore = undefined;
66 var connected = false,
67 syncing = false;
68
69 function middleware(store) {
70 unsubscribeHistory = history.listen(function (location) {
71 currentKey = location.key;
72 if (syncing) {
73 // Don't dispatch a new action if we're replaying location.
74 return;
75 }
76
77 store.dispatch(updateLocation(location));
78 });
79
80 connected = true;
81
82 return function (next) {
83 return function (action) {
84 if (action.type !== TRANSITION || !connected) {
85 next(action);
86 return;
87 }
88
89 // FIXME: Is it correct to swallow the TRANSITION action here and replace
90 // it with UPDATE_LOCATION instead? We could also use the same type in
91 // both places instead and just set the location on the action.
92
93 var method = action.method;
94 var arg = action.arg;
95
96 history[method](arg);
97 };
98 };
99 }
100
101 middleware.syncHistoryToStore = function (store) {
102 var selectRouterState = arguments.length <= 1 || arguments[1] === undefined ? SELECT_STATE : arguments[1];
103
104 var getRouterState = function getRouterState() {
105 return selectRouterState(store.getState());
106 };
107
108 var _getRouterState = getRouterState();
109
110 var initialLocation = _getRouterState.location;
111
112 unsubscribeStore = store.subscribe(function () {
113 var _getRouterState2 = getRouterState();
114
115 var location = _getRouterState2.location;
116
117 // If we're resetting to the beginning, use the saved initial value. We
118 // need to dispatch a new action at this point to populate the store
119 // appropriately.
120
121 if (!location) {
122 history.transitionTo(initialLocation);
123 return;
124 }
125
126 // Otherwise, if we need to update the history location, do so without
127 // dispatching a new action, as we're just bringing history in sync
128 // with the store.
129 if (location.key !== currentKey) {
130 syncing = true;
131 history.transitionTo(location);
132 syncing = false;
133 }
134 });
135 };
136
137 middleware.unsubscribe = function () {
138 unsubscribeHistory();
139 if (unsubscribeStore) {
140 unsubscribeStore();
141 }
142
143 connected = false;
144 };
145
146 return middleware;
147}