navigation-stack 0.5.3 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (210) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +144 -282
  3. package/karma.conf.cjs +1 -1
  4. package/lib/cjs/NavigationStack.js +138 -49
  5. package/lib/cjs/data-storage/DataStorage.js +7 -6
  6. package/lib/cjs/environment/InMemoryEnvironment.js +6 -0
  7. package/lib/cjs/{session/ServerSideRenderSession.js → environment/ServerSideRenderEnvironment.js} +5 -6
  8. package/lib/cjs/environment/WebBrowserEnvironment.js +6 -0
  9. package/lib/cjs/environment/log/InMemoryLog.js +23 -0
  10. package/lib/cjs/environment/log/WebBrowserLog.js +22 -0
  11. package/lib/cjs/{session → environment}/navigation/InMemoryNavigation.js +16 -5
  12. package/lib/cjs/{session → environment}/navigation/ServerSideNavigation.js +16 -7
  13. package/lib/cjs/{session → environment}/navigation/WebBrowserNavigation.js +48 -8
  14. package/lib/cjs/{session/navigation/error/ServerSideNavigationError.js → environment/navigation/error/ServerSideRedirectError.js} +2 -2
  15. package/lib/cjs/environment/scroll-position/WebBrowserScrollPosition.js +15 -0
  16. package/lib/cjs/getLocationBaseFromLocation.js +14 -0
  17. package/lib/cjs/getLocationUrl.js +3 -5
  18. package/lib/cjs/index.js +10 -16
  19. package/lib/cjs/navigationBlockers.js +34 -32
  20. package/lib/cjs/navigationBlockersEvaluation.js +150 -0
  21. package/lib/cjs/parseInputLocation.js +2 -2
  22. package/lib/cjs/parseQueryFromSearch.js +3 -6
  23. package/lib/cjs/parseQueryString.js +77 -0
  24. package/lib/cjs/scroll-position/ScrollPositionAutoSaver.js +7 -6
  25. package/lib/cjs/scroll-position/ScrollPositionRestoration.js +31 -27
  26. package/lib/cjs/scroll-position/ScrollPositionSaver.js +6 -4
  27. package/lib/cjs/session/Session.js +61 -26
  28. package/lib/cjs/session/subscription/Subscription.js +36 -18
  29. package/lib/cjs/stringifyQuery.js +66 -0
  30. package/lib/cjs/stringifyQueryAsSearch.js +14 -0
  31. package/lib/esm/NavigationStack.js +138 -49
  32. package/lib/esm/data-storage/DataStorage.js +7 -6
  33. package/lib/esm/environment/InMemoryEnvironment.js +6 -0
  34. package/lib/esm/environment/ServerSideRenderEnvironment.js +10 -0
  35. package/lib/esm/environment/WebBrowserEnvironment.js +6 -0
  36. package/lib/esm/environment/log/InMemoryLog.js +17 -0
  37. package/lib/esm/environment/log/WebBrowserLog.js +16 -0
  38. package/lib/esm/{session → environment}/navigation/InMemoryNavigation.js +16 -5
  39. package/lib/esm/{session → environment}/navigation/ServerSideNavigation.js +16 -7
  40. package/lib/esm/{session → environment}/navigation/WebBrowserNavigation.js +48 -8
  41. package/lib/esm/{session/navigation/error/ServerSideNavigationError.js → environment/navigation/error/ServerSideRedirectError.js} +1 -1
  42. package/lib/esm/environment/scroll-position/WebBrowserScrollPosition.js +15 -0
  43. package/lib/esm/getLocationBaseFromLocation.js +9 -0
  44. package/lib/esm/getLocationUrl.js +2 -5
  45. package/lib/esm/index.js +5 -8
  46. package/lib/esm/navigationBlockers.js +34 -32
  47. package/lib/esm/navigationBlockersEvaluation.js +145 -0
  48. package/lib/esm/parseInputLocation.js +2 -2
  49. package/lib/esm/parseQueryFromSearch.js +2 -6
  50. package/lib/esm/parseQueryString.js +72 -0
  51. package/lib/esm/scroll-position/ScrollPositionAutoSaver.js +7 -6
  52. package/lib/esm/scroll-position/ScrollPositionRestoration.js +31 -27
  53. package/lib/esm/scroll-position/ScrollPositionSaver.js +6 -4
  54. package/lib/esm/session/Session.js +61 -26
  55. package/lib/esm/session/subscription/Subscription.js +36 -18
  56. package/lib/esm/stringifyQuery.js +61 -0
  57. package/lib/esm/stringifyQueryAsSearch.js +8 -0
  58. package/lib/index.d.ts +180 -34
  59. package/package.json +4 -7
  60. package/src/NavigationStack.js +166 -56
  61. package/src/data-storage/DataStorage.js +9 -6
  62. package/src/environment/InMemoryEnvironment.js +6 -0
  63. package/src/environment/ServerSideRenderEnvironment.js +10 -0
  64. package/src/environment/WebBrowserEnvironment.js +6 -0
  65. package/src/environment/log/InMemoryLog.js +20 -0
  66. package/src/environment/log/WebBrowserLog.js +18 -0
  67. package/src/{session → environment}/navigation/InMemoryNavigation.js +16 -5
  68. package/src/{session → environment}/navigation/ServerSideNavigation.js +16 -7
  69. package/src/{session → environment}/navigation/WebBrowserNavigation.js +48 -8
  70. package/src/{session/navigation/error/ServerSideNavigationError.js → environment/navigation/error/ServerSideRedirectError.js} +1 -1
  71. package/src/environment/scroll-position/WebBrowserScrollPosition.js +15 -0
  72. package/src/getLocationBaseFromLocation.js +7 -0
  73. package/src/getLocationUrl.js +2 -5
  74. package/src/index.js +10 -13
  75. package/src/navigationBlockers.js +55 -34
  76. package/src/navigationBlockersEvaluation.js +161 -0
  77. package/src/parseInputLocation.js +2 -2
  78. package/src/parseQueryFromSearch.js +2 -6
  79. package/src/parseQueryString.js +81 -0
  80. package/src/scroll-position/ScrollPositionAutoSaver.js +10 -6
  81. package/src/scroll-position/ScrollPositionRestoration.js +36 -30
  82. package/src/scroll-position/ScrollPositionSaver.js +6 -4
  83. package/src/scroll-position/index.js +1 -1
  84. package/src/session/Session.js +68 -24
  85. package/src/session/subscription/Subscription.js +36 -11
  86. package/src/stringifyQuery.js +71 -0
  87. package/src/stringifyQueryAsSearch.js +9 -0
  88. package/test/NavigationStack.addBasePath.test.js +50 -0
  89. package/test/{redux/middleware/createNonProgrammaticNavigationBlockerMiddleware.test.js → NavigationStack.blockNonProgrammaticNavigationIfRequired.test.js} +51 -63
  90. package/test/{redux/middleware/createProgrammaticNavigationBlockerMiddleware.test.js → NavigationStack.blockProgrammaticNavigationIfRequired.test.js} +98 -78
  91. package/test/NavigationStack.general.test.js +68 -0
  92. package/test/NavigationStack.parseInputLocation.test.js +52 -0
  93. package/test/NavigationStack.removeBasePath.test.js +69 -0
  94. package/test/NavigationStack.test.js +97 -29
  95. package/test/data-storage/LocationDataStorage.test.js +3 -2
  96. package/test/index.js +7 -31
  97. package/test/index.test.js +4 -5
  98. package/test/parseQueryFromSearch.test.js +19 -0
  99. package/test/parseQueryString.test.js +18 -0
  100. package/test/scroll-position/ScrollPositionRestoration.test.js +34 -13
  101. package/test/scroll-position/createApp.js +8 -8
  102. package/test/scroll-position/withScrollableContainerAtIndexPageWithDisabledAutomaticScrollPositionRestoration.js +4 -4
  103. package/test/session/{InMemorySession.test.js → Session.InMemoryEnvironment.test.js} +10 -9
  104. package/test/session/{ServerSession.test.js → Session.ServerSideRenderEnvironment.test.js} +5 -4
  105. package/test/session/{WebBrowserSession.test.js → Session.WebBrowserEnvironment.test.js} +63 -13
  106. package/test/shouldWarn.js +44 -0
  107. package/test/stringifyQuery.test.js +65 -0
  108. package/types/index.d.ts +180 -34
  109. package/types/tsconfig.json +0 -1
  110. package/data-storage/package.json +0 -7
  111. package/lib/cjs/createSearchFromQuery.js +0 -13
  112. package/lib/cjs/debug.js +0 -12
  113. package/lib/cjs/redux/ActionTypes.js +0 -14
  114. package/lib/cjs/redux/ActionTypesInternal.js +0 -8
  115. package/lib/cjs/redux/Actions.js +0 -28
  116. package/lib/cjs/redux/createMiddlewares.js +0 -60
  117. package/lib/cjs/redux/index.js +0 -13
  118. package/lib/cjs/redux/internalLocationReducer.js +0 -14
  119. package/lib/cjs/redux/locationReducer.js +0 -13
  120. package/lib/cjs/redux/middleware/createAddInputLocationBasePathMiddleware.js +0 -32
  121. package/lib/cjs/redux/middleware/createNonProgrammaticNavigationBlockerMiddleware.js +0 -113
  122. package/lib/cjs/redux/middleware/createProgrammaticNavigationBlockerMiddleware.js +0 -94
  123. package/lib/cjs/redux/middleware/createRemoveOutputLocationBasePathMiddleware.js +0 -30
  124. package/lib/cjs/redux/middleware/createUpdateInternalLocationMiddleware.js +0 -73
  125. package/lib/cjs/redux/middleware/navigationOperationMiddleware.js +0 -40
  126. package/lib/cjs/redux/middleware/parseInputLocationMiddleware.js +0 -29
  127. package/lib/cjs/redux/middleware/updateLocationMiddleware.js +0 -34
  128. package/lib/cjs/session/InMemorySession.js +0 -22
  129. package/lib/cjs/session/WebBrowserSession.js +0 -20
  130. package/lib/data-storage/index.d.ts +0 -35
  131. package/lib/esm/createSearchFromQuery.js +0 -8
  132. package/lib/esm/debug.js +0 -7
  133. package/lib/esm/redux/ActionTypes.js +0 -9
  134. package/lib/esm/redux/ActionTypesInternal.js +0 -3
  135. package/lib/esm/redux/Actions.js +0 -22
  136. package/lib/esm/redux/createMiddlewares.js +0 -54
  137. package/lib/esm/redux/index.js +0 -4
  138. package/lib/esm/redux/internalLocationReducer.js +0 -8
  139. package/lib/esm/redux/locationReducer.js +0 -7
  140. package/lib/esm/redux/middleware/createAddInputLocationBasePathMiddleware.js +0 -27
  141. package/lib/esm/redux/middleware/createNonProgrammaticNavigationBlockerMiddleware.js +0 -108
  142. package/lib/esm/redux/middleware/createProgrammaticNavigationBlockerMiddleware.js +0 -88
  143. package/lib/esm/redux/middleware/createRemoveOutputLocationBasePathMiddleware.js +0 -25
  144. package/lib/esm/redux/middleware/createUpdateInternalLocationMiddleware.js +0 -68
  145. package/lib/esm/redux/middleware/navigationOperationMiddleware.js +0 -35
  146. package/lib/esm/redux/middleware/parseInputLocationMiddleware.js +0 -24
  147. package/lib/esm/redux/middleware/updateLocationMiddleware.js +0 -28
  148. package/lib/esm/session/InMemorySession.js +0 -15
  149. package/lib/esm/session/ServerSideRenderSession.js +0 -11
  150. package/lib/esm/session/WebBrowserSession.js +0 -13
  151. package/lib/redux/index.d.ts +0 -90
  152. package/lib/scroll-position/index.d.ts +0 -107
  153. package/redux/package.json +0 -7
  154. package/scroll-position/package.json +0 -7
  155. package/src/createSearchFromQuery.js +0 -9
  156. package/src/debug.js +0 -8
  157. package/src/redux/ActionTypes.js +0 -9
  158. package/src/redux/ActionTypesInternal.js +0 -3
  159. package/src/redux/Actions.js +0 -27
  160. package/src/redux/createMiddlewares.js +0 -65
  161. package/src/redux/index.js +0 -4
  162. package/src/redux/internalLocationReducer.js +0 -9
  163. package/src/redux/locationReducer.js +0 -8
  164. package/src/redux/middleware/createAddInputLocationBasePathMiddleware.js +0 -27
  165. package/src/redux/middleware/createNonProgrammaticNavigationBlockerMiddleware.js +0 -119
  166. package/src/redux/middleware/createProgrammaticNavigationBlockerMiddleware.js +0 -94
  167. package/src/redux/middleware/createRemoveOutputLocationBasePathMiddleware.js +0 -26
  168. package/src/redux/middleware/createUpdateInternalLocationMiddleware.js +0 -72
  169. package/src/redux/middleware/navigationOperationMiddleware.js +0 -34
  170. package/src/redux/middleware/parseInputLocationMiddleware.js +0 -23
  171. package/src/redux/middleware/updateLocationMiddleware.js +0 -28
  172. package/src/session/InMemorySession.js +0 -13
  173. package/src/session/ServerSideRenderSession.js +0 -9
  174. package/src/session/WebBrowserSession.js +0 -13
  175. package/test/middlewareTestUtil.js +0 -31
  176. package/test/redux/Action.test.js +0 -73
  177. package/test/redux/ActionTypes.test.js +0 -13
  178. package/test/redux/createMiddlewares.test.js +0 -96
  179. package/test/redux/index.test.js +0 -10
  180. package/test/redux/locationReducer.test.js +0 -39
  181. package/test/redux/middleware/createAddInputLocationBasePathMiddleware.test.js +0 -40
  182. package/test/redux/middleware/createRemoveOutputLocationBasePathMiddleware.test.js +0 -51
  183. package/test/redux/middleware/navigationOperationMiddleware.test.js +0 -78
  184. package/test/redux/middleware/parseInputLocationMiddleware.test.js +0 -62
  185. package/test/testUtil.js +0 -3
  186. package/types/data-storage/index.d.ts +0 -35
  187. package/types/redux/index.d.ts +0 -90
  188. package/types/scroll-position/index.d.ts +0 -107
  189. /package/lib/cjs/{session → environment}/lifecycle/InMemorySessionLifecycle.js +0 -0
  190. /package/lib/cjs/{session → environment}/lifecycle/WebBrowserSessionLifecycle.js +0 -0
  191. /package/lib/cjs/{session → environment}/lifecycle/page-lifecycle/PageLifecycle.js +0 -0
  192. /package/lib/cjs/{session → environment}/lifecycle/page-lifecycle/PageLifecycleInstance.js +0 -0
  193. /package/lib/cjs/{session → environment}/lifecycle/page-lifecycle/supportsConstructableEventTarget.js +0 -0
  194. /package/lib/cjs/{session → environment}/navigation/error/NavigationOutOfBoundsError.js +0 -0
  195. /package/lib/cjs/{session → environment}/navigation/operation/operations.js +0 -0
  196. /package/lib/esm/{session → environment}/lifecycle/InMemorySessionLifecycle.js +0 -0
  197. /package/lib/esm/{session → environment}/lifecycle/WebBrowserSessionLifecycle.js +0 -0
  198. /package/lib/esm/{session → environment}/lifecycle/page-lifecycle/PageLifecycle.js +0 -0
  199. /package/lib/esm/{session → environment}/lifecycle/page-lifecycle/PageLifecycleInstance.js +0 -0
  200. /package/lib/esm/{session → environment}/lifecycle/page-lifecycle/supportsConstructableEventTarget.js +0 -0
  201. /package/lib/esm/{session → environment}/navigation/error/NavigationOutOfBoundsError.js +0 -0
  202. /package/lib/esm/{session → environment}/navigation/operation/operations.js +0 -0
  203. /package/src/{session → environment}/lifecycle/InMemorySessionLifecycle.js +0 -0
  204. /package/src/{session → environment}/lifecycle/WebBrowserSessionLifecycle.js +0 -0
  205. /package/src/{session → environment}/lifecycle/page-lifecycle/PageLifecycle.js +0 -0
  206. /package/src/{session → environment}/lifecycle/page-lifecycle/PageLifecycleInstance.js +0 -0
  207. /package/src/{session → environment}/lifecycle/page-lifecycle/supportsConstructableEventTarget.js +0 -0
  208. /package/src/{session → environment}/navigation/error/NavigationOutOfBoundsError.js +0 -0
  209. /package/src/{session → environment}/navigation/operation/operations.js +0 -0
  210. /package/test/{parseInputLocationMiddleware.test.js → parseInputLocation.test.js} +0 -0
@@ -1,13 +0,0 @@
1
- import Session from './Session';
2
- import WebBrowserEnvironment from '../environment/WebBrowserEnvironment';
3
- import WebBrowserSessionLifecycle from './lifecycle/WebBrowserSessionLifecycle';
4
- import WebBrowserNavigation from './navigation/WebBrowserNavigation';
5
- export default class WebBrowserSession extends Session {
6
- constructor() {
7
- super({
8
- navigation: new WebBrowserNavigation()
9
- });
10
- this.environment = new WebBrowserEnvironment();
11
- this.lifecycle = new WebBrowserSessionLifecycle();
12
- }
13
- }
@@ -1,90 +0,0 @@
1
- import { InputLocation, Session } from '../index.d.js';
2
-
3
- export interface CreateMiddlewaresOptions {
4
- basePath?: string;
5
- }
6
-
7
- export function createMiddlewares(
8
- session: Session,
9
- options?: CreateMiddlewaresOptions,
10
- ): Middleware[];
11
-
12
- export const ActionTypes: {
13
- INIT: '@@navigation-stack/INIT';
14
- PUSH: '@@navigation-stack/PUSH';
15
- REPLACE: '@@navigation-stack/REPLACE';
16
- NAVIGATE: '@@navigation-stack/NAVIGATE';
17
- SHIFT: '@@navigation-stack/SHIFT';
18
- UPDATE: '@@navigation-stack/UPDATE';
19
- STOP: '@@navigation-stack/STOP';
20
- };
21
-
22
- export interface InitAction {
23
- type: (typeof ActionTypes)['INIT'];
24
- payload?: InputLocation;
25
- }
26
-
27
- export interface PushAction {
28
- type: (typeof ActionTypes)['PUSH'];
29
- payload: InputLocation;
30
- }
31
-
32
- export interface ReplaceAction {
33
- type: (typeof ActionTypes)['REPLACE'];
34
- payload: InputLocation;
35
- }
36
-
37
- export interface ShiftAction {
38
- type: (typeof ActionTypes)['SHIFT'];
39
- payload: number;
40
- }
41
-
42
- export interface DisposeAction {
43
- type: (typeof ActionTypes)['STOP'];
44
- }
45
-
46
- export type Action =
47
- | InitAction
48
- | PushAction
49
- | ReplaceAction
50
- | ShiftAction
51
- | DisposeAction;
52
-
53
- export const Actions: {
54
- init(initialLocation?: InputLocation): InitAction;
55
- push(location: InputLocation): PushAction;
56
- replace(location: InputLocation): ReplaceAction;
57
- shift(delta: number): ShiftAction;
58
- stop(): DisposeAction;
59
- };
60
-
61
- export const locationReducer: Reducer<Location, Action>;
62
-
63
- // The following types are copy-pasted from `redux`.
64
-
65
- interface ReduxAction<T = any> {
66
- type: T;
67
- }
68
-
69
- interface AnyAction extends ReduxAction {
70
- // Allows any extra properties to be defined in an action.
71
- [extraProps: string]: any;
72
- }
73
-
74
- interface Dispatch<A extends Action = AnyAction> {
75
- <T extends A>(action: T): T;
76
- }
77
-
78
- interface MiddlewareAPI<D extends Dispatch = Dispatch, S = any> {
79
- dispatch: D;
80
- getState(): S;
81
- }
82
-
83
- interface Middleware<S = any, D extends Dispatch = Dispatch> {
84
- (api: MiddlewareAPI<D, S>): (next: Dispatch) => (action: any) => any;
85
- }
86
-
87
- type Reducer<S = any, A extends Action = AnyAction> = (
88
- state: S | undefined,
89
- action: A,
90
- ) => S;
@@ -1,107 +0,0 @@
1
- // TypeScript Version: 3.0
2
-
3
- import { EnvironmentScrollPosition, Location, Session } from '../index.d.js';
4
-
5
- export { EnvironmentScrollPosition, Location, Session } from '../index.d.js';
6
-
7
- export {};
8
-
9
- export class ScrollPositionRestoration<
10
- ScrollableContainer = any,
11
- Anchor = any,
12
- > {
13
- constructor(
14
- session: Session<ScrollableContainer, Anchor>,
15
-
16
- // `_options` are currently only used in tests.
17
- _options?: {
18
- // `_options._shouldSetPageScrollPositionOnLocationChange`
19
- // isn't used in real life and is not part of the public API.
20
- // It's only used in tests.
21
- _shouldSetPageScrollPositionOnLocationChange?: (
22
- location: Location,
23
- prevLocation: Location | undefined,
24
- ) => boolean;
25
-
26
- // `_options._getSavedPageScrollPositionOnLocationChange`
27
- // isn't used in real life and is not part of the public API.
28
- // It's only used in tests.
29
- _getSavedPageScrollPositionOnLocationChange?: (
30
- location: Location,
31
- prevLocation: Location | undefined,
32
- ) => [number, number] | undefined;
33
-
34
- // Using this option, a developer could theoretically provide their own implementation
35
- // of setting a scroll position. For example, it could use "smooth" (animated) scrolling, etc.
36
- // This could be part of the public API if anyone provided a sensible real-world use case for it.
37
- _pageScrollPositionSetter?: ScrollPositionSetter<
38
- ScrollableContainer,
39
- Anchor
40
- >;
41
- },
42
- );
43
-
44
- addScrollableContainer(
45
- scrollableContainerKey: string,
46
- scrollableContainer: ScrollableContainer,
47
-
48
- // `_options` are currently only used in tests.
49
- _options?: {
50
- // `_options._shouldSetScrollPositionOnLocationChange`
51
- // isn't used in real life and is not part of the public API.
52
- // It's only used in tests.
53
- _shouldSetScrollPositionOnLocationChange?: (
54
- location: Location,
55
- prevLocation: Location | undefined,
56
- ) => boolean;
57
-
58
- // `_options._getSavedScrollPositionOnLocationChange`
59
- // isn't used in real life and is not part of the public API.
60
- // It's only used in tests.
61
- _getSavedScrollPositionOnLocationChange?: (
62
- location: Location,
63
- prevLocation: Location | undefined,
64
- ) => [number, number] | undefined;
65
-
66
- // Using this option, a developer could theoretically provide their own implementation
67
- // of setting a scroll position. For example, it could use "smooth" (animated) scrolling, etc.
68
- // This could be part of the public API if anyone provided a sensible real-world use case for it.
69
- _scrollPositionSetter: ScrollPositionSetter<ScrollableContainer, Anchor>;
70
- },
71
- ): () => void;
72
-
73
- locationRendered: (location: Location) => Promise<void>;
74
-
75
- stop(): void;
76
-
77
- // `_enableSavingScrollPosition()` and `_disableSavingScrollPosition()`
78
- // aren't used in real life and are not part of the public API.
79
- // They're only used in tests.
80
- _enableSavingScrollPosition(): void;
81
-
82
- // `_enableSavingScrollPosition()` and `_disableSavingScrollPosition()`
83
- // aren't used in real life and are not part of the public API.
84
- // They're only used in tests.
85
- _disableSavingScrollPosition(): void;
86
- }
87
-
88
- // Theoretically, a developer could pass their own `ScrollPositionSetter` implementation
89
- // when calling `.addScrollableContainer()` or
90
- export interface ScrollPositionSetter<ScrollableContainer, Anchor> {
91
- // Sets scroll position of a page or a scrollable element.
92
- // Returns a `Promise` that resolves when it has finished setting the scroll position.
93
- set(
94
- // When setting page scroll position, `scrollableContainer` is `undefined`.
95
- // When setting scrollable element scroll position, `scrollableContainer` is the scrollable element.
96
- scrollableContainer: ScrollableContainer,
97
- // When setting page scroll position, it could be either an anchor or numeric coordinates.
98
- // When setting scrollable element scroll position, it could only be numeric coordinates.
99
- scrollPositionOrAnchor: Anchor | [number, number],
100
- // `scrollPosition` provides the API for setting scroll position according to the environment.
101
- // For example, `WebBrowserScrollPosition` provides the methods for setting scroll position in a web browser.
102
- scrollPosition: EnvironmentScrollPosition<ScrollableContainer, Anchor>,
103
- ): Promise<void>;
104
-
105
- // Cancels any pending (or in-progress) setting of scroll position.
106
- cancel(): void;
107
- }
@@ -1,7 +0,0 @@
1
- {
2
- "private": true,
3
- "name": "navigation-stack/redux",
4
- "main": "./../lib/cjs/redux/index.js",
5
- "module": "./../lib/esm/redux/index.js",
6
- "types": "./../lib/redux/index.d.ts"
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "private": true,
3
- "name": "navigation-stack/scroll-position",
4
- "main": "./../lib/cjs/scroll-position/index.js",
5
- "module": "./../lib/esm/scroll-position/index.js",
6
- "types": "./../lib/scroll-position/index.d.ts"
7
- }
@@ -1,9 +0,0 @@
1
- import { stringify as stringifyQuery } from 'query-string';
2
-
3
- export default function createSearchFromQuery(query) {
4
- const queryString = stringifyQuery(query);
5
- if (queryString) {
6
- return `?${queryString}`;
7
- }
8
- return undefined;
9
- }
package/src/debug.js DELETED
@@ -1,8 +0,0 @@
1
- const DEBUG = false;
2
-
3
- export default function debug(...args) {
4
- if (DEBUG) {
5
- // eslint-disable-next-line no-console
6
- console.log(...args);
7
- }
8
- }
@@ -1,9 +0,0 @@
1
- export default {
2
- INIT: '@@navigation-stack/INIT',
3
- PUSH: '@@navigation-stack/PUSH',
4
- REPLACE: '@@navigation-stack/REPLACE',
5
- NAVIGATE: '@@navigation-stack/NAVIGATE',
6
- SHIFT: '@@navigation-stack/SHIFT',
7
- UPDATE: '@@navigation-stack/UPDATE',
8
- STOP: '@@navigation-stack/STOP',
9
- };
@@ -1,3 +0,0 @@
1
- export default {
2
- INTERNAL_LOCATION_UPDATE: '@@navigation-stack/INTERNAL_LOCATION_UPDATE',
3
- };
@@ -1,27 +0,0 @@
1
- import ActionTypes from './ActionTypes';
2
-
3
- export default {
4
- init: (initialLocation) => ({
5
- type: ActionTypes.INIT,
6
- payload: initialLocation,
7
- }),
8
-
9
- push: (location) => ({
10
- type: ActionTypes.PUSH,
11
- payload: location,
12
- }),
13
-
14
- replace: (location) => ({
15
- type: ActionTypes.REPLACE,
16
- payload: location,
17
- }),
18
-
19
- shift: (delta) => ({
20
- type: ActionTypes.SHIFT,
21
- payload: delta,
22
- }),
23
-
24
- stop: () => ({
25
- type: ActionTypes.STOP,
26
- }),
27
- };
@@ -1,65 +0,0 @@
1
- import createAddInputLocationBasePathMiddleware from './middleware/createAddInputLocationBasePathMiddleware';
2
- import createNonProgrammaticNavigationBlockerMiddleware from './middleware/createNonProgrammaticNavigationBlockerMiddleware';
3
- import createProgrammaticNavigationBlockerMiddleware from './middleware/createProgrammaticNavigationBlockerMiddleware';
4
- import createRemoveOutputLocationBasePathMiddleware from './middleware/createRemoveOutputLocationBasePathMiddleware';
5
- import createUpdateInternalLocationMiddleware from './middleware/createUpdateInternalLocationMiddleware';
6
- import navigationActionMiddleware from './middleware/navigationOperationMiddleware';
7
- import parseInputLocationMiddleware from './middleware/parseInputLocationMiddleware';
8
- import updateLocationMiddleware from './middleware/updateLocationMiddleware';
9
-
10
- export default function createMiddlewares(session, options) {
11
- // Allows temporarily ignoring location update events.
12
- let shouldIgnoreNavigationLocationSubscriptionEvents = false;
13
- const ignoreNavigationLocationSubscriptionEvents = (func) => {
14
- shouldIgnoreNavigationLocationSubscriptionEvents = true;
15
- func();
16
- shouldIgnoreNavigationLocationSubscriptionEvents = false;
17
- };
18
-
19
- const middlewares = [
20
- // Validates that the action "payload" (input location) is a proper `NormalizedInputLocation`.
21
- parseInputLocationMiddleware,
22
-
23
- // Transforms a "PUSH" / "REPLACE" action into a "NAVIGATE" action.
24
- navigationActionMiddleware,
25
-
26
- // If a website is hosted under a certain path (`basePath`)
27
- // then this middleware will automatically hide that starting segment from the `pathname` of `location`s.
28
- createAddInputLocationBasePathMiddleware(options && options.basePath),
29
-
30
- // Allows blocking navigation.
31
- // Handles `NAVIGATE` actions dispatched by the application itself.
32
- createProgrammaticNavigationBlockerMiddleware(session),
33
-
34
- // This "middleware" performs the actual navigation according to the `session` being used.
35
- // For example, when `WebBrowserSession` is used, it calls methods of the `history` object.
36
- createUpdateInternalLocationMiddleware(session, {
37
- shouldIgnoreNavigationLocationSubscriptionEvents: () =>
38
- shouldIgnoreNavigationLocationSubscriptionEvents,
39
- }),
40
-
41
- // If a website is hosted under a certain path (`basePath`)
42
- // then this middleware will automatically hide that starting segment from the `pathname` of `location`s.
43
- createRemoveOutputLocationBasePathMiddleware(options && options.basePath),
44
-
45
- // Allows blocking navigation.
46
- // Handles location `UPDATE` actions dispatched in response to location update events.
47
- createNonProgrammaticNavigationBlockerMiddleware(session, {
48
- ignoreNavigationLocationSubscriptionEvents,
49
- }),
50
- ];
51
-
52
- // Add `updateLocationMiddleware()`.
53
- // It dispatches an `UPDATE` action with the new location
54
- // so that the reducer could update it in global state.
55
- //
56
- // If `_internalLocationReducer` option is passed,
57
- // it will not add this middleware. This is only used in tests.
58
- //
59
- // eslint-disable-next-line no-underscore-dangle
60
- if (!(options && options._internalLocationReducer)) {
61
- middlewares.push(updateLocationMiddleware);
62
- }
63
-
64
- return middlewares;
65
- }
@@ -1,4 +0,0 @@
1
- export Actions from './Actions';
2
- export ActionTypes from './ActionTypes';
3
- export createMiddlewares from './createMiddlewares';
4
- export locationReducer from './locationReducer';
@@ -1,9 +0,0 @@
1
- import ActionTypesInternal from './ActionTypesInternal';
2
-
3
- export default function internalLocationReducer(state, action) {
4
- // eslint-disable-next-line no-underscore-dangle
5
- if (action.type === ActionTypesInternal.INTERNAL_LOCATION_UPDATE) {
6
- return action.payload;
7
- }
8
- return state;
9
- }
@@ -1,8 +0,0 @@
1
- import ActionTypes from './ActionTypes';
2
-
3
- export default function locationReducer(state, action) {
4
- if (action.type === ActionTypes.UPDATE) {
5
- return action.payload;
6
- }
7
- return state;
8
- }
@@ -1,27 +0,0 @@
1
- import { addBasePath } from '../../basePath';
2
- import ActionTypes from '../ActionTypes';
3
-
4
- // Creates a "middleware" that, when a website is hosted under a certain path (`basePath`),
5
- // automatically hides that starting segment from the `pathname` of `location`s.
6
- export default function createAddInputLocationBasePathMiddleware(basePath) {
7
- return function addInputLocationBasePathMiddleware() {
8
- return (next) => (action) => {
9
- const { type, payload } = action;
10
-
11
- switch (type) {
12
- // Transforms `NAVIGATE` action payload (`location`).
13
- case ActionTypes.NAVIGATE:
14
- return next({
15
- type,
16
- payload: {
17
- ...payload,
18
- location: addBasePath(payload.location, basePath),
19
- },
20
- });
21
-
22
- default:
23
- return next(action);
24
- }
25
- };
26
- };
27
- }
@@ -1,119 +0,0 @@
1
- import getLocationFromInternalLocation from '../../getLocationFromInternalLocation';
2
- import isPromise from '../../isPromise';
3
- import {
4
- getNavigationBlockers,
5
- runNavigationBlockers,
6
- } from '../../navigationBlockers';
7
- import NavigationOperations from '../../session/navigation/operation/operations';
8
- import ActionTypesInternal from '../ActionTypesInternal';
9
- import { createNavigationBlockersEvaluationStatus } from './createProgrammaticNavigationBlockerMiddleware';
10
-
11
- // Creates a "middleware" that applies navigation blockers for non-programmatic navigation,
12
- // i.e. the navigation that wasn't triggered by the application code and was triggered, say, by the user.
13
- // It also handles programmatic `SHIFT` navigation because it doesn't know the new location until
14
- // the environment performs the `delta` navigation and then tells the new location to `navigation-stack`.
15
- export default function createNonProgrammaticNavigationBlockerMiddleware(
16
- session,
17
- { ignoreNavigationLocationSubscriptionEvents },
18
- ) {
19
- return function nonProgrammaticNavigationBlockerMiddleware() {
20
- return (next) => (action) => {
21
- const { type, payload } = action;
22
-
23
- // Declaring `result` variable here fixes ESLint error:
24
- // "Unexpected lexical declaration in case block".
25
- let result;
26
-
27
- switch (type) {
28
- // One could ask: Why run navigation blockers on `UPDATE` Redux action?
29
- // Why not just run navigation blockers on `NAVIGATE` and `SHIFT` Redux action?
30
- // The reason why it handles `UPDATE` Redux actions here is because
31
- // `NAVIGATE` Redux actions are only emitted for programmatic "push" or "replace" navigation
32
- // initiated by the application code, and there're other cases of navigation such as
33
- // programmatic "shift" navigation or when the user manually clicks "Back" or "Forward" button
34
- // in a web browser. And even if a "shift" navigation is initiated by the application code,
35
- // it still doesn't know yet what the new location is gonna be cause it only knows the `delta`.
36
- // Such "other" cases could only be handled by reacting to an `UPDATE` Redux action
37
- // which is only emitted after the URL in the browser's address bar has changed.
38
- //
39
- // There's no real drawback in reacting to an `UPDATE` Redux action "post factum" because
40
- // from the application's point of view the address bar doesn't matter and even doesn't exist.
41
- // All that exists from the application's point of view is the `location` object in the Redux state.
42
- // Until the `location` object in the Redux state is updated, the old page is still rendered.
43
- // The appliation is only concerned with the updates of the `location` object in the Redux state
44
- // and completely ignores any updates to the URL in the web browser's address bar.
45
- //
46
- // So here, the "middleware" attempts to prevent or allow navigation that has already happened
47
- // in the web browser's address bar but hasn't yet happened in Redux state.
48
- // For example, it could be a user clicking a "Back"/"Forward" button in their web browser.
49
- // If such navigation should've been blocked, it will simply not update the `locaiton` object in Redux state,
50
- // and it will also "rewind" the change of the URL in the web browser's address bar so that it's consistent
51
- // with the `location` in Redux state.
52
- //
53
- // eslint-disable-next-line no-underscore-dangle
54
- case ActionTypesInternal.INTERNAL_LOCATION_UPDATE:
55
- // Programmatic `PUSH`/`REPLACE` actions are handled in another middleware.
56
- if (
57
- payload.operation === NavigationOperations.PUSH ||
58
- payload.operation === NavigationOperations.REPLACE
59
- ) {
60
- return next(action);
61
- }
62
-
63
- // If no navigation blockers to run, don't do anything.
64
- if (getNavigationBlockers(session).length === 0) {
65
- return next(action);
66
- }
67
-
68
- // If it was the initial page load or a redirect,
69
- // it's not really a navigation that could be rolled back.
70
- if (payload.delta === 0) {
71
- return next(action);
72
- }
73
-
74
- result = runNavigationBlockers(
75
- getNavigationBlockers(session),
76
- // Here `getLocationFromInternalLocation(payload)` is `Location`.
77
- getLocationFromInternalLocation(payload),
78
- );
79
-
80
- if (isPromise(result)) {
81
- const status = createNavigationBlockersEvaluationStatus(session);
82
-
83
- // While location blockers are running, rewind to the previous location.
84
- ignoreNavigationLocationSubscriptionEvents(() => {
85
- session.shift(-payload.delta);
86
- });
87
-
88
- result.then((promiseResult) => {
89
- if (promiseResult) {
90
- // Navigation blocked.
91
- // Already rewound to a previous location.
92
- } else if (!status.cancelled) {
93
- // Navigation not blocked.
94
- // Rewind back to the new location.
95
- ignoreNavigationLocationSubscriptionEvents(() => {
96
- session.shift(payload.delta);
97
- });
98
- // Update the location.
99
- next(action);
100
- }
101
- });
102
- } else if (result) {
103
- // Prevent the navigation: rewind to the previous location.
104
- ignoreNavigationLocationSubscriptionEvents(() => {
105
- session.shift(-payload.delta);
106
- });
107
- } else {
108
- // Update the location.
109
- return next(action);
110
- }
111
- // eslint-disable-next-line consistent-return
112
- return;
113
-
114
- default:
115
- return next(action);
116
- }
117
- };
118
- };
119
- }
@@ -1,94 +0,0 @@
1
- import isPromise from '../../isPromise';
2
- import {
3
- getNavigationBlockers,
4
- removeAllNavigationBlockers,
5
- runNavigationBlockers,
6
- } from '../../navigationBlockers';
7
- import ActionTypes from '../ActionTypes';
8
-
9
- export function createNavigationBlockersEvaluationStatus(session) {
10
- /* eslint-disable no-underscore-dangle */
11
- if (session._navigationBlockersEvaluationStatus) {
12
- session._navigationBlockersEvaluationStatus.cancelled = true;
13
- }
14
- session._navigationBlockersEvaluationStatus = { cancelled: false };
15
- return session._navigationBlockersEvaluationStatus;
16
- }
17
-
18
- // Creates a "middleware" that applies navigation blockers for programmatic navigation,
19
- // i.e. the navigation that was triggered by the application code.
20
- // This only includes `PUSH` and `REPLACE` navigation, and other programmatic types of navigation
21
- // such as `SHIFT` aren't able to be handled here due to not yet having `location` info,
22
- // so they're handled in a different middleware.
23
- export default function createProgrammaticNavigationBlockerMiddleware(
24
- session,
25
- ) {
26
- return function programmaticNavigationBlockerMiddleware() {
27
- return (next) => (action) => {
28
- const { type, payload } = action;
29
-
30
- // Declaring `result` variable here fixes ESLint error:
31
- // "Unexpected lexical declaration in case block".
32
- let result;
33
-
34
- switch (type) {
35
- // Prevent or allow navigation that was initiated by the application
36
- // by dispatching a `.push()` or `.replace()` action.
37
- //
38
- // It doesn't handle `.shift()` navigation actions because it doesn't yet know
39
- // the `location` that it's gonna `shift` to. Instead, it waits for the web browser
40
- // to "shift" to that `location` and then reads it and rewinds the "shift"
41
- // if it should've been blocked. That is handled by another "navigation blocker" middleware.
42
- //
43
- // This type of "shifting" and then rewinding the "shift" doesn't really matter to the application at all.
44
- // From the application's point of view, all of that doesn't matter and even doesn't exist.
45
- // All that exists from the application's point of view is the `location` object in the Redux state.
46
- // Until the `location` object in the Redux state is updated, the old page is still rendered.
47
- // The appliation is only concerned with the updates of the `location` object in the Redux state
48
- // and completely ignores any updates to the URL in the web browser's address bar.
49
- //
50
- case ActionTypes.NAVIGATE:
51
- // `resultValue` variable name works around a stupid javascript error:
52
- // "Cannot redeclare block-scoped variable 'result'".
53
- result = runNavigationBlockers(
54
- getNavigationBlockers(session),
55
- // Here `payload.location` is `LocationBase`.
56
- payload.location,
57
- );
58
- if (isPromise(result)) {
59
- const status = createNavigationBlockersEvaluationStatus(session);
60
- // eslint-disable-next-line consistent-return
61
- result.then((resultValue) => {
62
- if (!status.cancelled) {
63
- if (!resultValue) {
64
- return next(action);
65
- }
66
- }
67
- });
68
- } else if (!result) {
69
- return next(action);
70
- }
71
- // eslint-disable-next-line consistent-return
72
- return;
73
-
74
- // Programmatic SHIFT actions aren't handled here.
75
- // Instead, they're handled in non-programmatic navigation blocker middleware.
76
- // The rationale is that there's no `location` argument on "SHIFT" actions,
77
- // so the navigation blockers don't know yet what is the new location gonna be.
78
- // They have to wait for the environment to restore the new location
79
- // and then tell it to `navigation-stack` by calling a listener.
80
- case ActionTypes.SHIFT:
81
- // New `location` isn't known yet. Proceed without blocking anything.
82
- return next(action);
83
-
84
- // Remove any navigation blockers on `STOP` event.
85
- case ActionTypes.STOP:
86
- removeAllNavigationBlockers(session);
87
- return next(action);
88
-
89
- default:
90
- return next(action);
91
- }
92
- };
93
- };
94
- }
@@ -1,26 +0,0 @@
1
- import { removeBasePath } from '../../basePath';
2
- import ActionTypesInternal from '../ActionTypesInternal';
3
-
4
- // Creates a "middleware" that, when a website is hosted under a certain path (`basePath`),
5
- // automatically hides that starting segment from the `pathname` of `location`s.
6
- export default function createRemoveOutputLocationBasePathMiddleware(
7
- basePath,
8
- ) {
9
- return function removeOutputLocationBasePathMiddleware() {
10
- return (next) => (action) => {
11
- const { type, payload } = action;
12
-
13
- switch (type) {
14
- // Transforms `UPDATE` action payload (input `location`).
15
- case ActionTypesInternal.INTERNAL_LOCATION_UPDATE:
16
- return next({
17
- type,
18
- payload: removeBasePath(payload, basePath),
19
- });
20
-
21
- default:
22
- return next(action);
23
- }
24
- };
25
- };
26
- }