UNPKG

18.4 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 { InjectionToken, NgModule, ErrorHandler, Inject } from '@angular/core';
7import { NavigationStart, RoutesRecognized, NavigationCancel, NavigationError, NavigationEnd, Router } from '@angular/router';
8import { select, Store, createSelector } from '@ngrx/store';
9import { withLatestFrom } from 'rxjs/operators';
10
11/**
12 * @fileoverview added by tsickle
13 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
14 */
15/**
16 * An action dispatched when a router navigation request is fired.
17 * @type {?}
18 */
19const ROUTER_REQUEST = '@ngrx/router-store/request';
20/**
21 * An action dispatched when the router navigates.
22 * @type {?}
23 */
24const ROUTER_NAVIGATION = '@ngrx/router-store/navigation';
25/**
26 * An action dispatched when the router cancels navigation.
27 * @type {?}
28 */
29const ROUTER_CANCEL = '@ngrx/router-store/cancel';
30/**
31 * An action dispatched when the router errors.
32 * @type {?}
33 */
34const ROUTER_ERROR = '@ngrx/router-store/error';
35/**
36 * An action dispatched after navigation has ended and new route is active.
37 * @type {?}
38 */
39const ROUTER_NAVIGATED = '@ngrx/router-store/navigated';
40
41/**
42 * @fileoverview added by tsickle
43 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
44 */
45/**
46 * @template T
47 * @param {?} state
48 * @param {?} action
49 * @return {?}
50 */
51function routerReducer(state, action) {
52 // Allow compilation with strictFunctionTypes - ref: #1344
53 /** @type {?} */
54 const routerAction = (/** @type {?} */ (action));
55 switch (routerAction.type) {
56 case ROUTER_NAVIGATION:
57 case ROUTER_ERROR:
58 case ROUTER_CANCEL:
59 return {
60 state: routerAction.payload.routerState,
61 navigationId: routerAction.payload.event.id,
62 };
63 default:
64 return (/** @type {?} */ (state));
65 }
66}
67
68/**
69 * @fileoverview added by tsickle
70 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
71 */
72/**
73 * @abstract
74 * @template T
75 */
76class RouterStateSerializer {
77}
78
79/**
80 * @fileoverview added by tsickle
81 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
82 */
83class DefaultRouterStateSerializer {
84 /**
85 * @param {?} routerState
86 * @return {?}
87 */
88 serialize(routerState) {
89 return {
90 root: this.serializeRoute(routerState.root),
91 url: routerState.url,
92 };
93 }
94 /**
95 * @private
96 * @param {?} route
97 * @return {?}
98 */
99 serializeRoute(route) {
100 /** @type {?} */
101 const children = route.children.map((/**
102 * @param {?} c
103 * @return {?}
104 */
105 c => this.serializeRoute(c)));
106 return {
107 params: route.params,
108 paramMap: route.paramMap,
109 data: route.data,
110 url: route.url,
111 outlet: route.outlet,
112 routeConfig: route.routeConfig
113 ? {
114 component: route.routeConfig.component,
115 path: route.routeConfig.path,
116 pathMatch: route.routeConfig.pathMatch,
117 redirectTo: route.routeConfig.redirectTo,
118 outlet: route.routeConfig.outlet,
119 }
120 : null,
121 queryParams: route.queryParams,
122 queryParamMap: route.queryParamMap,
123 fragment: route.fragment,
124 component: (/** @type {?} */ ((route.routeConfig
125 ? route.routeConfig.component
126 : undefined))),
127 root: (/** @type {?} */ (undefined)),
128 parent: (/** @type {?} */ (undefined)),
129 firstChild: children[0],
130 pathFromRoot: (/** @type {?} */ (undefined)),
131 children,
132 };
133 }
134}
135
136/**
137 * @fileoverview added by tsickle
138 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
139 */
140class MinimalRouterStateSerializer {
141 /**
142 * @param {?} routerState
143 * @return {?}
144 */
145 serialize(routerState) {
146 return {
147 root: this.serializeRoute(routerState.root),
148 url: routerState.url,
149 };
150 }
151 /**
152 * @private
153 * @param {?} route
154 * @return {?}
155 */
156 serializeRoute(route) {
157 /** @type {?} */
158 const children = route.children.map((/**
159 * @param {?} c
160 * @return {?}
161 */
162 c => this.serializeRoute(c)));
163 return {
164 params: route.params,
165 data: route.data,
166 url: route.url,
167 outlet: route.outlet,
168 routeConfig: route.routeConfig
169 ? {
170 path: route.routeConfig.path,
171 pathMatch: route.routeConfig.pathMatch,
172 redirectTo: route.routeConfig.redirectTo,
173 outlet: route.routeConfig.outlet,
174 }
175 : null,
176 queryParams: route.queryParams,
177 fragment: route.fragment,
178 firstChild: children[0],
179 children,
180 };
181 }
182}
183
184/**
185 * @fileoverview added by tsickle
186 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
187 */
188/** @enum {number} */
189const NavigationActionTiming = {
190 PreActivation: 1,
191 PostActivation: 2,
192};
193NavigationActionTiming[NavigationActionTiming.PreActivation] = 'PreActivation';
194NavigationActionTiming[NavigationActionTiming.PostActivation] = 'PostActivation';
195/** @type {?} */
196const _ROUTER_CONFIG = new InjectionToken('@ngrx/router-store Internal Configuration');
197/** @type {?} */
198const ROUTER_CONFIG = new InjectionToken('@ngrx/router-store Configuration');
199/** @type {?} */
200const DEFAULT_ROUTER_FEATURENAME = 'router';
201/**
202 * @param {?} config
203 * @return {?}
204 */
205function _createRouterConfig(config) {
206 return Object.assign({ stateKey: DEFAULT_ROUTER_FEATURENAME, serializer: DefaultRouterStateSerializer, navigationActionTiming: NavigationActionTiming.PreActivation }, config);
207}
208/** @enum {number} */
209const RouterTrigger = {
210 NONE: 1,
211 ROUTER: 2,
212 STORE: 3,
213};
214RouterTrigger[RouterTrigger.NONE] = 'NONE';
215RouterTrigger[RouterTrigger.ROUTER] = 'ROUTER';
216RouterTrigger[RouterTrigger.STORE] = 'STORE';
217/**
218 * Connects RouterModule with StoreModule.
219 *
220 * During the navigation, before any guards or resolvers run, the router will dispatch
221 * a ROUTER_NAVIGATION action, which has the following signature:
222 *
223 * ```
224 * export type RouterNavigationPayload = {
225 * routerState: SerializedRouterStateSnapshot,
226 * event: RoutesRecognized
227 * }
228 * ```
229 *
230 * Either a reducer or an effect can be invoked in response to this action.
231 * If the invoked reducer throws, the navigation will be canceled.
232 *
233 * If navigation gets canceled because of a guard, a ROUTER_CANCEL action will be
234 * dispatched. If navigation results in an error, a ROUTER_ERROR action will be dispatched.
235 *
236 * Both ROUTER_CANCEL and ROUTER_ERROR contain the store state before the navigation
237 * which can be used to restore the consistency of the store.
238 *
239 * Usage:
240 *
241 * ```typescript
242 * \@NgModule({
243 * declarations: [AppCmp, SimpleCmp],
244 * imports: [
245 * BrowserModule,
246 * StoreModule.forRoot(mapOfReducers),
247 * RouterModule.forRoot([
248 * { path: '', component: SimpleCmp },
249 * { path: 'next', component: SimpleCmp }
250 * ]),
251 * StoreRouterConnectingModule.forRoot()
252 * ],
253 * bootstrap: [AppCmp]
254 * })
255 * export class AppModule {
256 * }
257 * ```
258 */
259class StoreRouterConnectingModule {
260 /**
261 * @param {?} store
262 * @param {?} router
263 * @param {?} serializer
264 * @param {?} errorHandler
265 * @param {?} config
266 */
267 constructor(store, router, serializer, errorHandler, config) {
268 this.store = store;
269 this.router = router;
270 this.serializer = serializer;
271 this.errorHandler = errorHandler;
272 this.config = config;
273 this.lastEvent = null;
274 this.trigger = RouterTrigger.NONE;
275 this.stateKey = (/** @type {?} */ (this.config.stateKey));
276 this.setUpStoreStateListener();
277 this.setUpRouterEventsListener();
278 }
279 /**
280 * @template T
281 * @param {?=} config
282 * @return {?}
283 */
284 static forRoot(config = {}) {
285 return {
286 ngModule: StoreRouterConnectingModule,
287 providers: [
288 { provide: _ROUTER_CONFIG, useValue: config },
289 {
290 provide: ROUTER_CONFIG,
291 useFactory: _createRouterConfig,
292 deps: [_ROUTER_CONFIG],
293 },
294 {
295 provide: RouterStateSerializer,
296 useClass: config.serializer
297 ? config.serializer
298 : config.routerState === 1 /* Minimal */
299 ? MinimalRouterStateSerializer
300 : DefaultRouterStateSerializer,
301 },
302 ],
303 };
304 }
305 /**
306 * @private
307 * @return {?}
308 */
309 setUpStoreStateListener() {
310 this.store
311 .pipe(select((/** @type {?} */ (this.stateKey))), withLatestFrom(this.store))
312 .subscribe((/**
313 * @param {?} __0
314 * @return {?}
315 */
316 ([routerStoreState, storeState]) => {
317 this.navigateIfNeeded(routerStoreState, storeState);
318 }));
319 }
320 /**
321 * @private
322 * @param {?} routerStoreState
323 * @param {?} storeState
324 * @return {?}
325 */
326 navigateIfNeeded(routerStoreState, storeState) {
327 if (!routerStoreState || !routerStoreState.state) {
328 return;
329 }
330 if (this.trigger === RouterTrigger.ROUTER) {
331 return;
332 }
333 if (this.lastEvent instanceof NavigationStart) {
334 return;
335 }
336 /** @type {?} */
337 const url = routerStoreState.state.url;
338 if (this.router.url !== url) {
339 this.storeState = storeState;
340 this.trigger = RouterTrigger.STORE;
341 this.router.navigateByUrl(url).catch((/**
342 * @param {?} error
343 * @return {?}
344 */
345 error => {
346 this.errorHandler.handleError(error);
347 }));
348 }
349 }
350 /**
351 * @private
352 * @return {?}
353 */
354 setUpRouterEventsListener() {
355 /** @type {?} */
356 const dispatchNavLate = this.config.navigationActionTiming ===
357 NavigationActionTiming.PostActivation;
358 /** @type {?} */
359 let routesRecognized;
360 this.router.events
361 .pipe(withLatestFrom(this.store))
362 .subscribe((/**
363 * @param {?} __0
364 * @return {?}
365 */
366 ([event, storeState]) => {
367 this.lastEvent = event;
368 if (event instanceof NavigationStart) {
369 this.routerState = this.serializer.serialize(this.router.routerState.snapshot);
370 if (this.trigger !== RouterTrigger.STORE) {
371 this.storeState = storeState;
372 this.dispatchRouterRequest(event);
373 }
374 }
375 else if (event instanceof RoutesRecognized) {
376 routesRecognized = event;
377 if (!dispatchNavLate && this.trigger !== RouterTrigger.STORE) {
378 this.dispatchRouterNavigation(event);
379 }
380 }
381 else if (event instanceof NavigationCancel) {
382 this.dispatchRouterCancel(event);
383 this.reset();
384 }
385 else if (event instanceof NavigationError) {
386 this.dispatchRouterError(event);
387 this.reset();
388 }
389 else if (event instanceof NavigationEnd) {
390 if (this.trigger !== RouterTrigger.STORE) {
391 if (dispatchNavLate) {
392 this.dispatchRouterNavigation(routesRecognized);
393 }
394 this.dispatchRouterNavigated(event);
395 }
396 this.reset();
397 }
398 }));
399 }
400 /**
401 * @private
402 * @param {?} event
403 * @return {?}
404 */
405 dispatchRouterRequest(event) {
406 this.dispatchRouterAction(ROUTER_REQUEST, { event });
407 }
408 /**
409 * @private
410 * @param {?} lastRoutesRecognized
411 * @return {?}
412 */
413 dispatchRouterNavigation(lastRoutesRecognized) {
414 /** @type {?} */
415 const nextRouterState = this.serializer.serialize(lastRoutesRecognized.state);
416 this.dispatchRouterAction(ROUTER_NAVIGATION, {
417 routerState: nextRouterState,
418 event: new RoutesRecognized(lastRoutesRecognized.id, lastRoutesRecognized.url, lastRoutesRecognized.urlAfterRedirects, nextRouterState),
419 });
420 }
421 /**
422 * @private
423 * @param {?} event
424 * @return {?}
425 */
426 dispatchRouterCancel(event) {
427 this.dispatchRouterAction(ROUTER_CANCEL, {
428 storeState: this.storeState,
429 event,
430 });
431 }
432 /**
433 * @private
434 * @param {?} event
435 * @return {?}
436 */
437 dispatchRouterError(event) {
438 this.dispatchRouterAction(ROUTER_ERROR, {
439 storeState: this.storeState,
440 event: new NavigationError(event.id, event.url, `${event}`),
441 });
442 }
443 /**
444 * @private
445 * @param {?} event
446 * @return {?}
447 */
448 dispatchRouterNavigated(event) {
449 /** @type {?} */
450 const routerState = this.serializer.serialize(this.router.routerState.snapshot);
451 this.dispatchRouterAction(ROUTER_NAVIGATED, { event, routerState });
452 }
453 /**
454 * @private
455 * @param {?} type
456 * @param {?} payload
457 * @return {?}
458 */
459 dispatchRouterAction(type, payload) {
460 this.trigger = RouterTrigger.ROUTER;
461 try {
462 this.store.dispatch({
463 type,
464 payload: Object.assign({ routerState: this.routerState }, payload, { event: this.config.routerState === 1 /* Minimal */
465 ? { id: payload.event.id, url: payload.event.url }
466 : payload.event }),
467 });
468 }
469 finally {
470 this.trigger = RouterTrigger.NONE;
471 }
472 }
473 /**
474 * @private
475 * @return {?}
476 */
477 reset() {
478 this.trigger = RouterTrigger.NONE;
479 this.storeState = null;
480 this.routerState = null;
481 }
482}
483StoreRouterConnectingModule.decorators = [
484 { type: NgModule, args: [{},] }
485];
486/** @nocollapse */
487StoreRouterConnectingModule.ctorParameters = () => [
488 { type: Store },
489 { type: Router },
490 { type: RouterStateSerializer },
491 { type: ErrorHandler },
492 { type: undefined, decorators: [{ type: Inject, args: [ROUTER_CONFIG,] }] }
493];
494
495/**
496 * @fileoverview added by tsickle
497 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
498 */
499/**
500 * @template V
501 * @param {?} selectState
502 * @return {?}
503 */
504function getSelectors(selectState) {
505 /** @type {?} */
506 const selectRouterState = createSelector(selectState, (/**
507 * @param {?} router
508 * @return {?}
509 */
510 router => router && router.state));
511 /** @type {?} */
512 const selectCurrentRoute = createSelector(selectRouterState, (/**
513 * @param {?} routerState
514 * @return {?}
515 */
516 routerState => {
517 if (!routerState) {
518 return undefined;
519 }
520 /** @type {?} */
521 let route = routerState.root;
522 while (route.firstChild) {
523 route = route.firstChild;
524 }
525 return route;
526 }));
527 /** @type {?} */
528 const selectQueryParams = createSelector(selectCurrentRoute, (/**
529 * @param {?} route
530 * @return {?}
531 */
532 route => route && route.queryParams));
533 /** @type {?} */
534 const selectQueryParam = (/**
535 * @param {?} param
536 * @return {?}
537 */
538 (param) => createSelector(selectQueryParams, (/**
539 * @param {?} params
540 * @return {?}
541 */
542 params => params && params[param])));
543 /** @type {?} */
544 const selectRouteParams = createSelector(selectCurrentRoute, (/**
545 * @param {?} route
546 * @return {?}
547 */
548 route => route && route.params));
549 /** @type {?} */
550 const selectRouteParam = (/**
551 * @param {?} param
552 * @return {?}
553 */
554 (param) => createSelector(selectRouteParams, (/**
555 * @param {?} params
556 * @return {?}
557 */
558 params => params && params[param])));
559 /** @type {?} */
560 const selectRouteData = createSelector(selectCurrentRoute, (/**
561 * @param {?} route
562 * @return {?}
563 */
564 route => route && route.data));
565 /** @type {?} */
566 const selectUrl = createSelector(selectRouterState, (/**
567 * @param {?} routerState
568 * @return {?}
569 */
570 routerState => routerState && routerState.url));
571 return {
572 selectCurrentRoute,
573 selectQueryParams,
574 selectQueryParam,
575 selectRouteParams,
576 selectRouteParam,
577 selectRouteData,
578 selectUrl,
579 };
580}
581
582/**
583 * @fileoverview added by tsickle
584 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
585 */
586
587/**
588 * @fileoverview added by tsickle
589 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
590 */
591
592/**
593 * @fileoverview added by tsickle
594 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
595 */
596
597/**
598 * Generated bundle index. Do not edit.
599 */
600
601export { _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 };
602//# sourceMappingURL=router-store.js.map