UNPKG

15.8 kBJavaScriptView Raw
1/**
2 * @license NgRx 8.5.2
3 * (c) 2015-2018 Brandon Roberts, Mike Ryan, Rob Wormald, Victor Savkin
4 * License: MIT
5 */
6import { __assign, __read, __decorate, __param, __metadata } from 'tslib';
7import { InjectionToken, NgModule, Inject, ErrorHandler } from '@angular/core';
8import { NavigationStart, RoutesRecognized, NavigationCancel, NavigationError, NavigationEnd, Router } from '@angular/router';
9import { select, Store, createSelector } from '@ngrx/store';
10import { withLatestFrom } from 'rxjs/operators';
11
12/**
13 * An action dispatched when a router navigation request is fired.
14 */
15var ROUTER_REQUEST = '@ngrx/router-store/request';
16/**
17 * An action dispatched when the router navigates.
18 */
19var ROUTER_NAVIGATION = '@ngrx/router-store/navigation';
20/**
21 * An action dispatched when the router cancels navigation.
22 */
23var ROUTER_CANCEL = '@ngrx/router-store/cancel';
24/**
25 * An action dispatched when the router errors.
26 */
27var ROUTER_ERROR = '@ngrx/router-store/error';
28/**
29 * An action dispatched after navigation has ended and new route is active.
30 */
31var ROUTER_NAVIGATED = '@ngrx/router-store/navigated';
32
33function routerReducer(state, action) {
34 // Allow compilation with strictFunctionTypes - ref: #1344
35 var routerAction = action;
36 switch (routerAction.type) {
37 case ROUTER_NAVIGATION:
38 case ROUTER_ERROR:
39 case ROUTER_CANCEL:
40 return {
41 state: routerAction.payload.routerState,
42 navigationId: routerAction.payload.event.id,
43 };
44 default:
45 return state;
46 }
47}
48
49var RouterStateSerializer = /** @class */ (function () {
50 function RouterStateSerializer() {
51 }
52 return RouterStateSerializer;
53}());
54
55var DefaultRouterStateSerializer = /** @class */ (function () {
56 function DefaultRouterStateSerializer() {
57 }
58 DefaultRouterStateSerializer.prototype.serialize = function (routerState) {
59 return {
60 root: this.serializeRoute(routerState.root),
61 url: routerState.url,
62 };
63 };
64 DefaultRouterStateSerializer.prototype.serializeRoute = function (route) {
65 var _this = this;
66 var children = route.children.map(function (c) { return _this.serializeRoute(c); });
67 return {
68 params: route.params,
69 paramMap: route.paramMap,
70 data: route.data,
71 url: route.url,
72 outlet: route.outlet,
73 routeConfig: route.routeConfig
74 ? {
75 component: route.routeConfig.component,
76 path: route.routeConfig.path,
77 pathMatch: route.routeConfig.pathMatch,
78 redirectTo: route.routeConfig.redirectTo,
79 outlet: route.routeConfig.outlet,
80 }
81 : null,
82 queryParams: route.queryParams,
83 queryParamMap: route.queryParamMap,
84 fragment: route.fragment,
85 component: (route.routeConfig
86 ? route.routeConfig.component
87 : undefined),
88 root: undefined,
89 parent: undefined,
90 firstChild: children[0],
91 pathFromRoot: undefined,
92 children: children,
93 };
94 };
95 return DefaultRouterStateSerializer;
96}());
97
98var MinimalRouterStateSerializer = /** @class */ (function () {
99 function MinimalRouterStateSerializer() {
100 }
101 MinimalRouterStateSerializer.prototype.serialize = function (routerState) {
102 return {
103 root: this.serializeRoute(routerState.root),
104 url: routerState.url,
105 };
106 };
107 MinimalRouterStateSerializer.prototype.serializeRoute = function (route) {
108 var _this = this;
109 var children = route.children.map(function (c) { return _this.serializeRoute(c); });
110 return {
111 params: route.params,
112 data: route.data,
113 url: route.url,
114 outlet: route.outlet,
115 routeConfig: route.routeConfig
116 ? {
117 path: route.routeConfig.path,
118 pathMatch: route.routeConfig.pathMatch,
119 redirectTo: route.routeConfig.redirectTo,
120 outlet: route.routeConfig.outlet,
121 }
122 : null,
123 queryParams: route.queryParams,
124 fragment: route.fragment,
125 firstChild: children[0],
126 children: children,
127 };
128 };
129 return MinimalRouterStateSerializer;
130}());
131
132var NavigationActionTiming;
133(function (NavigationActionTiming) {
134 NavigationActionTiming[NavigationActionTiming["PreActivation"] = 1] = "PreActivation";
135 NavigationActionTiming[NavigationActionTiming["PostActivation"] = 2] = "PostActivation";
136})(NavigationActionTiming || (NavigationActionTiming = {}));
137var _ROUTER_CONFIG = new InjectionToken('@ngrx/router-store Internal Configuration');
138var ROUTER_CONFIG = new InjectionToken('@ngrx/router-store Configuration');
139var DEFAULT_ROUTER_FEATURENAME = 'router';
140function _createRouterConfig(config) {
141 return __assign({ stateKey: DEFAULT_ROUTER_FEATURENAME, serializer: DefaultRouterStateSerializer, navigationActionTiming: NavigationActionTiming.PreActivation }, config);
142}
143var RouterTrigger;
144(function (RouterTrigger) {
145 RouterTrigger[RouterTrigger["NONE"] = 1] = "NONE";
146 RouterTrigger[RouterTrigger["ROUTER"] = 2] = "ROUTER";
147 RouterTrigger[RouterTrigger["STORE"] = 3] = "STORE";
148})(RouterTrigger || (RouterTrigger = {}));
149/**
150 * Connects RouterModule with StoreModule.
151 *
152 * During the navigation, before any guards or resolvers run, the router will dispatch
153 * a ROUTER_NAVIGATION action, which has the following signature:
154 *
155 * ```
156 * export type RouterNavigationPayload = {
157 * routerState: SerializedRouterStateSnapshot,
158 * event: RoutesRecognized
159 * }
160 * ```
161 *
162 * Either a reducer or an effect can be invoked in response to this action.
163 * If the invoked reducer throws, the navigation will be canceled.
164 *
165 * If navigation gets canceled because of a guard, a ROUTER_CANCEL action will be
166 * dispatched. If navigation results in an error, a ROUTER_ERROR action will be dispatched.
167 *
168 * Both ROUTER_CANCEL and ROUTER_ERROR contain the store state before the navigation
169 * which can be used to restore the consistency of the store.
170 *
171 * Usage:
172 *
173 * ```typescript
174 * @NgModule({
175 * declarations: [AppCmp, SimpleCmp],
176 * imports: [
177 * BrowserModule,
178 * StoreModule.forRoot(mapOfReducers),
179 * RouterModule.forRoot([
180 * { path: '', component: SimpleCmp },
181 * { path: 'next', component: SimpleCmp }
182 * ]),
183 * StoreRouterConnectingModule.forRoot()
184 * ],
185 * bootstrap: [AppCmp]
186 * })
187 * export class AppModule {
188 * }
189 * ```
190 */
191var StoreRouterConnectingModule = /** @class */ (function () {
192 function StoreRouterConnectingModule(store, router, serializer, errorHandler, config) {
193 this.store = store;
194 this.router = router;
195 this.serializer = serializer;
196 this.errorHandler = errorHandler;
197 this.config = config;
198 this.lastEvent = null;
199 this.trigger = RouterTrigger.NONE;
200 this.stateKey = this.config.stateKey;
201 this.setUpStoreStateListener();
202 this.setUpRouterEventsListener();
203 }
204 StoreRouterConnectingModule_1 = StoreRouterConnectingModule;
205 StoreRouterConnectingModule.forRoot = function (config) {
206 if (config === void 0) { config = {}; }
207 return {
208 ngModule: StoreRouterConnectingModule_1,
209 providers: [
210 { provide: _ROUTER_CONFIG, useValue: config },
211 {
212 provide: ROUTER_CONFIG,
213 useFactory: _createRouterConfig,
214 deps: [_ROUTER_CONFIG],
215 },
216 {
217 provide: RouterStateSerializer,
218 useClass: config.serializer
219 ? config.serializer
220 : config.routerState === 1 /* Minimal */
221 ? MinimalRouterStateSerializer
222 : DefaultRouterStateSerializer,
223 },
224 ],
225 };
226 };
227 StoreRouterConnectingModule.prototype.setUpStoreStateListener = function () {
228 var _this = this;
229 this.store
230 .pipe(select(this.stateKey), withLatestFrom(this.store))
231 .subscribe(function (_a) {
232 var _b = __read(_a, 2), routerStoreState = _b[0], storeState = _b[1];
233 _this.navigateIfNeeded(routerStoreState, storeState);
234 });
235 };
236 StoreRouterConnectingModule.prototype.navigateIfNeeded = function (routerStoreState, storeState) {
237 var _this = this;
238 if (!routerStoreState || !routerStoreState.state) {
239 return;
240 }
241 if (this.trigger === RouterTrigger.ROUTER) {
242 return;
243 }
244 if (this.lastEvent instanceof NavigationStart) {
245 return;
246 }
247 var url = routerStoreState.state.url;
248 if (this.router.url !== url) {
249 this.storeState = storeState;
250 this.trigger = RouterTrigger.STORE;
251 this.router.navigateByUrl(url).catch(function (error) {
252 _this.errorHandler.handleError(error);
253 });
254 }
255 };
256 StoreRouterConnectingModule.prototype.setUpRouterEventsListener = function () {
257 var _this = this;
258 var dispatchNavLate = this.config.navigationActionTiming ===
259 NavigationActionTiming.PostActivation;
260 var routesRecognized;
261 this.router.events
262 .pipe(withLatestFrom(this.store))
263 .subscribe(function (_a) {
264 var _b = __read(_a, 2), event = _b[0], storeState = _b[1];
265 _this.lastEvent = event;
266 if (event instanceof NavigationStart) {
267 _this.routerState = _this.serializer.serialize(_this.router.routerState.snapshot);
268 if (_this.trigger !== RouterTrigger.STORE) {
269 _this.storeState = storeState;
270 _this.dispatchRouterRequest(event);
271 }
272 }
273 else if (event instanceof RoutesRecognized) {
274 routesRecognized = event;
275 if (!dispatchNavLate && _this.trigger !== RouterTrigger.STORE) {
276 _this.dispatchRouterNavigation(event);
277 }
278 }
279 else if (event instanceof NavigationCancel) {
280 _this.dispatchRouterCancel(event);
281 _this.reset();
282 }
283 else if (event instanceof NavigationError) {
284 _this.dispatchRouterError(event);
285 _this.reset();
286 }
287 else if (event instanceof NavigationEnd) {
288 if (_this.trigger !== RouterTrigger.STORE) {
289 if (dispatchNavLate) {
290 _this.dispatchRouterNavigation(routesRecognized);
291 }
292 _this.dispatchRouterNavigated(event);
293 }
294 _this.reset();
295 }
296 });
297 };
298 StoreRouterConnectingModule.prototype.dispatchRouterRequest = function (event) {
299 this.dispatchRouterAction(ROUTER_REQUEST, { event: event });
300 };
301 StoreRouterConnectingModule.prototype.dispatchRouterNavigation = function (lastRoutesRecognized) {
302 var nextRouterState = this.serializer.serialize(lastRoutesRecognized.state);
303 this.dispatchRouterAction(ROUTER_NAVIGATION, {
304 routerState: nextRouterState,
305 event: new RoutesRecognized(lastRoutesRecognized.id, lastRoutesRecognized.url, lastRoutesRecognized.urlAfterRedirects, nextRouterState),
306 });
307 };
308 StoreRouterConnectingModule.prototype.dispatchRouterCancel = function (event) {
309 this.dispatchRouterAction(ROUTER_CANCEL, {
310 storeState: this.storeState,
311 event: event,
312 });
313 };
314 StoreRouterConnectingModule.prototype.dispatchRouterError = function (event) {
315 this.dispatchRouterAction(ROUTER_ERROR, {
316 storeState: this.storeState,
317 event: new NavigationError(event.id, event.url, "" + event),
318 });
319 };
320 StoreRouterConnectingModule.prototype.dispatchRouterNavigated = function (event) {
321 var routerState = this.serializer.serialize(this.router.routerState.snapshot);
322 this.dispatchRouterAction(ROUTER_NAVIGATED, { event: event, routerState: routerState });
323 };
324 StoreRouterConnectingModule.prototype.dispatchRouterAction = function (type, payload) {
325 this.trigger = RouterTrigger.ROUTER;
326 try {
327 this.store.dispatch({
328 type: type,
329 payload: __assign({ routerState: this.routerState }, payload, { event: this.config.routerState === 1 /* Minimal */
330 ? { id: payload.event.id, url: payload.event.url }
331 : payload.event }),
332 });
333 }
334 finally {
335 this.trigger = RouterTrigger.NONE;
336 }
337 };
338 StoreRouterConnectingModule.prototype.reset = function () {
339 this.trigger = RouterTrigger.NONE;
340 this.storeState = null;
341 this.routerState = null;
342 };
343 var StoreRouterConnectingModule_1;
344 StoreRouterConnectingModule = StoreRouterConnectingModule_1 = __decorate([
345 NgModule({}),
346 __param(4, Inject(ROUTER_CONFIG)),
347 __metadata("design:paramtypes", [Store,
348 Router,
349 RouterStateSerializer,
350 ErrorHandler, Object])
351 ], StoreRouterConnectingModule);
352 return StoreRouterConnectingModule;
353}());
354
355function getSelectors(selectState) {
356 var selectRouterState = createSelector(selectState, function (router) { return router && router.state; });
357 var selectCurrentRoute = createSelector(selectRouterState, function (routerState) {
358 if (!routerState) {
359 return undefined;
360 }
361 var route = routerState.root;
362 while (route.firstChild) {
363 route = route.firstChild;
364 }
365 return route;
366 });
367 var selectQueryParams = createSelector(selectCurrentRoute, function (route) { return route && route.queryParams; });
368 var selectQueryParam = function (param) {
369 return createSelector(selectQueryParams, function (params) { return params && params[param]; });
370 };
371 var selectRouteParams = createSelector(selectCurrentRoute, function (route) { return route && route.params; });
372 var selectRouteParam = function (param) {
373 return createSelector(selectRouteParams, function (params) { return params && params[param]; });
374 };
375 var selectRouteData = createSelector(selectCurrentRoute, function (route) { return route && route.data; });
376 var selectUrl = createSelector(selectRouterState, function (routerState) { return routerState && routerState.url; });
377 return {
378 selectCurrentRoute: selectCurrentRoute,
379 selectQueryParams: selectQueryParams,
380 selectQueryParam: selectQueryParam,
381 selectRouteParams: selectRouteParams,
382 selectRouteParam: selectRouteParam,
383 selectRouteData: selectRouteData,
384 selectUrl: selectUrl,
385 };
386}
387
388/**
389 * DO NOT EDIT
390 *
391 * This file is automatically generated at build
392 */
393
394/**
395 * Generated bundle index. Do not edit.
396 */
397
398export { _ROUTER_CONFIG as ɵngrx_modules_router_store_router_store_a, _createRouterConfig as ɵngrx_modules_router_store_router_store_b, ROUTER_ERROR, ROUTER_CANCEL, ROUTER_NAVIGATION, ROUTER_NAVIGATED, ROUTER_REQUEST, routerReducer, StoreRouterConnectingModule, NavigationActionTiming, ROUTER_CONFIG, DEFAULT_ROUTER_FEATURENAME, RouterStateSerializer, DefaultRouterStateSerializer, MinimalRouterStateSerializer, getSelectors };
399//# sourceMappingURL=router-store.js.map