@react-navigation/native 6.0.8 → 6.0.11

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.
@@ -0,0 +1,240 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = createMemoryHistory;
7
+
8
+ var _nonSecure = require("nanoid/non-secure");
9
+
10
+ function createMemoryHistory() {
11
+ let index = 0;
12
+ let items = []; // Pending callbacks for `history.go(n)`
13
+ // We might modify the callback stored if it was interrupted, so we have a ref to identify it
14
+
15
+ const pending = [];
16
+
17
+ const interrupt = () => {
18
+ // If another history operation was performed we need to interrupt existing ones
19
+ // This makes sure that calls such as `history.replace` after `history.go` don't happen
20
+ // Since otherwise it won't be correct if something else has changed
21
+ pending.forEach(it => {
22
+ const cb = it.cb;
23
+
24
+ it.cb = () => cb(true);
25
+ });
26
+ };
27
+
28
+ const history = {
29
+ get index() {
30
+ var _window$history$state;
31
+
32
+ // We store an id in the state instead of an index
33
+ // Index could get out of sync with in-memory values if page reloads
34
+ const id = (_window$history$state = window.history.state) === null || _window$history$state === void 0 ? void 0 : _window$history$state.id;
35
+
36
+ if (id) {
37
+ const index = items.findIndex(item => item.id === id);
38
+ return index > -1 ? index : 0;
39
+ }
40
+
41
+ return 0;
42
+ },
43
+
44
+ get(index) {
45
+ return items[index];
46
+ },
47
+
48
+ backIndex(_ref) {
49
+ let {
50
+ path
51
+ } = _ref;
52
+
53
+ // We need to find the index from the element before current to get closest path to go back to
54
+ for (let i = index - 1; i >= 0; i--) {
55
+ const item = items[i];
56
+
57
+ if (item.path === path) {
58
+ return i;
59
+ }
60
+ }
61
+
62
+ return -1;
63
+ },
64
+
65
+ push(_ref2) {
66
+ let {
67
+ path,
68
+ state
69
+ } = _ref2;
70
+ interrupt();
71
+ const id = (0, _nonSecure.nanoid)(); // When a new entry is pushed, all the existing entries after index will be inaccessible
72
+ // So we remove any existing entries after the current index to clean them up
73
+
74
+ items = items.slice(0, index + 1);
75
+ items.push({
76
+ path,
77
+ state,
78
+ id
79
+ });
80
+ index = items.length - 1; // We pass empty string for title because it's ignored in all browsers except safari
81
+ // We don't store state object in history.state because:
82
+ // - browsers have limits on how big it can be, and we don't control the size
83
+ // - while not recommended, there could be non-serializable data in state
84
+
85
+ window.history.pushState({
86
+ id
87
+ }, '', path);
88
+ },
89
+
90
+ replace(_ref3) {
91
+ var _window$history$state2, _window$history$state3;
92
+
93
+ let {
94
+ path,
95
+ state
96
+ } = _ref3;
97
+ interrupt();
98
+ const id = (_window$history$state2 = (_window$history$state3 = window.history.state) === null || _window$history$state3 === void 0 ? void 0 : _window$history$state3.id) !== null && _window$history$state2 !== void 0 ? _window$history$state2 : (0, _nonSecure.nanoid)();
99
+
100
+ if (!items.length || items.findIndex(item => item.id === id) < 0) {
101
+ // There are two scenarios for creating an array with only one history record:
102
+ // - When loaded id not found in the items array, this function by default will replace
103
+ // the first item. We need to keep only the new updated object, otherwise it will break
104
+ // the page when navigating forward in history.
105
+ // - This is the first time any state modifications are done
106
+ // So we need to push the entry as there's nothing to replace
107
+ items = [{
108
+ path,
109
+ state,
110
+ id
111
+ }];
112
+ index = 0;
113
+ } else {
114
+ items[index] = {
115
+ path,
116
+ state,
117
+ id
118
+ };
119
+ }
120
+
121
+ window.history.replaceState({
122
+ id
123
+ }, '', path);
124
+ },
125
+
126
+ // `history.go(n)` is asynchronous, there are couple of things to keep in mind:
127
+ // - it won't do anything if we can't go `n` steps, the `popstate` event won't fire.
128
+ // - each `history.go(n)` call will trigger a separate `popstate` event with correct location.
129
+ // - the `popstate` event fires before the next frame after calling `history.go(n)`.
130
+ // This method differs from `history.go(n)` in the sense that it'll go back as many steps it can.
131
+ go(n) {
132
+ interrupt(); // To guard against unexpected navigation out of the app we will assume that browser history is only as deep as the length of our memory
133
+ // history. If we don't have an item to navigate to then update our index and navigate as far as we can without taking the user out of the app.
134
+
135
+ const nextIndex = index + n;
136
+ const lastItemIndex = items.length - 1;
137
+
138
+ if (n < 0 && !items[nextIndex]) {
139
+ // Attempted to navigate beyond the first index. Negating the current index will align the browser history with the first item.
140
+ n = -index;
141
+ index = 0;
142
+ } else if (n > 0 && nextIndex > lastItemIndex) {
143
+ // Attempted to navigate past the last index. Calculate how many indices away from the last index and go there.
144
+ n = lastItemIndex - index;
145
+ index = lastItemIndex;
146
+ } else {
147
+ index = nextIndex;
148
+ }
149
+
150
+ if (n === 0) {
151
+ return;
152
+ } // When we call `history.go`, `popstate` will fire when there's history to go back to
153
+ // So we need to somehow handle following cases:
154
+ // - There's history to go back, `history.go` is called, and `popstate` fires
155
+ // - `history.go` is called multiple times, we need to resolve on respective `popstate`
156
+ // - No history to go back, but `history.go` was called, browser has no API to detect it
157
+
158
+
159
+ return new Promise((resolve, reject) => {
160
+ const done = interrupted => {
161
+ clearTimeout(timer);
162
+
163
+ if (interrupted) {
164
+ reject(new Error('History was changed during navigation.'));
165
+ return;
166
+ } // There seems to be a bug in Chrome regarding updating the title
167
+ // If we set a title just before calling `history.go`, the title gets lost
168
+ // However the value of `document.title` is still what we set it to
169
+ // It's just not displayed in the tab bar
170
+ // To update the tab bar, we need to reset the title to something else first (e.g. '')
171
+ // And set the title to what it was before so it gets applied
172
+ // It won't work without setting it to empty string coz otherwise title isn't changing
173
+ // Which means that the browser won't do anything after setting the title
174
+
175
+
176
+ const {
177
+ title
178
+ } = window.document;
179
+ window.document.title = '';
180
+ window.document.title = title;
181
+ resolve();
182
+ };
183
+
184
+ pending.push({
185
+ ref: done,
186
+ cb: done
187
+ }); // If navigation didn't happen within 100ms, assume that it won't happen
188
+ // This may not be accurate, but hopefully it won't take so much time
189
+ // In Chrome, navigation seems to happen instantly in next microtask
190
+ // But on Firefox, it seems to take much longer, around 50ms from our testing
191
+ // We're using a hacky timeout since there doesn't seem to be way to know for sure
192
+
193
+ const timer = setTimeout(() => {
194
+ const index = pending.findIndex(it => it.ref === done);
195
+
196
+ if (index > -1) {
197
+ pending[index].cb();
198
+ pending.splice(index, 1);
199
+ }
200
+ }, 100);
201
+
202
+ const onPopState = () => {
203
+ var _window$history$state4;
204
+
205
+ const id = (_window$history$state4 = window.history.state) === null || _window$history$state4 === void 0 ? void 0 : _window$history$state4.id;
206
+ const currentIndex = items.findIndex(item => item.id === id); // Fix createMemoryHistory.index variable's value
207
+ // as it may go out of sync when navigating in the browser.
208
+
209
+ index = Math.max(currentIndex, 0);
210
+ const last = pending.pop();
211
+ window.removeEventListener('popstate', onPopState);
212
+ last === null || last === void 0 ? void 0 : last.cb();
213
+ };
214
+
215
+ window.addEventListener('popstate', onPopState);
216
+ window.history.go(n);
217
+ });
218
+ },
219
+
220
+ // The `popstate` event is triggered when history changes, except `pushState` and `replaceState`
221
+ // If we call `history.go(n)` ourselves, we don't want it to trigger the listener
222
+ // Here we normalize it so that only external changes (e.g. user pressing back/forward) trigger the listener
223
+ listen(listener) {
224
+ const onPopState = () => {
225
+ if (pending.length) {
226
+ // This was triggered by `history.go(n)`, we shouldn't call the listener
227
+ return;
228
+ }
229
+
230
+ listener();
231
+ };
232
+
233
+ window.addEventListener('popstate', onPopState);
234
+ return () => window.removeEventListener('popstate', onPopState);
235
+ }
236
+
237
+ };
238
+ return history;
239
+ }
240
+ //# sourceMappingURL=createMemoryHistory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["createMemoryHistory.tsx"],"names":["createMemoryHistory","index","items","pending","interrupt","forEach","it","cb","history","id","window","state","findIndex","item","get","backIndex","path","i","push","slice","length","pushState","replace","replaceState","go","n","nextIndex","lastItemIndex","Promise","resolve","reject","done","interrupted","clearTimeout","timer","Error","title","document","ref","setTimeout","splice","onPopState","currentIndex","Math","max","last","pop","removeEventListener","addEventListener","listen","listener"],"mappings":"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","sourcesContent":["import type { NavigationState } from '@react-navigation/core';\nimport { nanoid } from 'nanoid/non-secure';\n\ntype HistoryRecord = {\n // Unique identifier for this record to match it with window.history.state\n id: string;\n // Navigation state object for the history entry\n state: NavigationState;\n // Path of the history entry\n path: string;\n};\n\nexport default function createMemoryHistory() {\n let index = 0;\n let items: HistoryRecord[] = [];\n\n // Pending callbacks for `history.go(n)`\n // We might modify the callback stored if it was interrupted, so we have a ref to identify it\n const pending: { ref: unknown; cb: (interrupted?: boolean) => void }[] = [];\n\n const interrupt = () => {\n // If another history operation was performed we need to interrupt existing ones\n // This makes sure that calls such as `history.replace` after `history.go` don't happen\n // Since otherwise it won't be correct if something else has changed\n pending.forEach((it) => {\n const cb = it.cb;\n it.cb = () => cb(true);\n });\n };\n\n const history = {\n get index(): number {\n // We store an id in the state instead of an index\n // Index could get out of sync with in-memory values if page reloads\n const id = window.history.state?.id;\n\n if (id) {\n const index = items.findIndex((item) => item.id === id);\n\n return index > -1 ? index : 0;\n }\n\n return 0;\n },\n\n get(index: number) {\n return items[index];\n },\n\n backIndex({ path }: { path: string }) {\n // We need to find the index from the element before current to get closest path to go back to\n for (let i = index - 1; i >= 0; i--) {\n const item = items[i];\n\n if (item.path === path) {\n return i;\n }\n }\n\n return -1;\n },\n\n push({ path, state }: { path: string; state: NavigationState }) {\n interrupt();\n\n const id = nanoid();\n\n // When a new entry is pushed, all the existing entries after index will be inaccessible\n // So we remove any existing entries after the current index to clean them up\n items = items.slice(0, index + 1);\n\n items.push({ path, state, id });\n index = items.length - 1;\n\n // We pass empty string for title because it's ignored in all browsers except safari\n // We don't store state object in history.state because:\n // - browsers have limits on how big it can be, and we don't control the size\n // - while not recommended, there could be non-serializable data in state\n window.history.pushState({ id }, '', path);\n },\n\n replace({ path, state }: { path: string; state: NavigationState }) {\n interrupt();\n\n const id = window.history.state?.id ?? nanoid();\n\n if (!items.length || items.findIndex((item) => item.id === id) < 0) {\n // There are two scenarios for creating an array with only one history record:\n // - When loaded id not found in the items array, this function by default will replace\n // the first item. We need to keep only the new updated object, otherwise it will break\n // the page when navigating forward in history.\n // - This is the first time any state modifications are done\n // So we need to push the entry as there's nothing to replace\n items = [{ path, state, id }];\n index = 0;\n } else {\n items[index] = { path, state, id };\n }\n\n window.history.replaceState({ id }, '', path);\n },\n\n // `history.go(n)` is asynchronous, there are couple of things to keep in mind:\n // - it won't do anything if we can't go `n` steps, the `popstate` event won't fire.\n // - each `history.go(n)` call will trigger a separate `popstate` event with correct location.\n // - the `popstate` event fires before the next frame after calling `history.go(n)`.\n // This method differs from `history.go(n)` in the sense that it'll go back as many steps it can.\n go(n: number) {\n interrupt();\n\n // To guard against unexpected navigation out of the app we will assume that browser history is only as deep as the length of our memory\n // history. If we don't have an item to navigate to then update our index and navigate as far as we can without taking the user out of the app.\n const nextIndex = index + n;\n const lastItemIndex = items.length - 1;\n if (n < 0 && !items[nextIndex]) {\n // Attempted to navigate beyond the first index. Negating the current index will align the browser history with the first item.\n n = -index;\n index = 0;\n } else if (n > 0 && nextIndex > lastItemIndex) {\n // Attempted to navigate past the last index. Calculate how many indices away from the last index and go there.\n n = lastItemIndex - index;\n index = lastItemIndex;\n } else {\n index = nextIndex;\n }\n\n if (n === 0) {\n return;\n }\n\n // When we call `history.go`, `popstate` will fire when there's history to go back to\n // So we need to somehow handle following cases:\n // - There's history to go back, `history.go` is called, and `popstate` fires\n // - `history.go` is called multiple times, we need to resolve on respective `popstate`\n // - No history to go back, but `history.go` was called, browser has no API to detect it\n return new Promise<void>((resolve, reject) => {\n const done = (interrupted?: boolean) => {\n clearTimeout(timer);\n\n if (interrupted) {\n reject(new Error('History was changed during navigation.'));\n return;\n }\n\n // There seems to be a bug in Chrome regarding updating the title\n // If we set a title just before calling `history.go`, the title gets lost\n // However the value of `document.title` is still what we set it to\n // It's just not displayed in the tab bar\n // To update the tab bar, we need to reset the title to something else first (e.g. '')\n // And set the title to what it was before so it gets applied\n // It won't work without setting it to empty string coz otherwise title isn't changing\n // Which means that the browser won't do anything after setting the title\n const { title } = window.document;\n\n window.document.title = '';\n window.document.title = title;\n\n resolve();\n };\n\n pending.push({ ref: done, cb: done });\n\n // If navigation didn't happen within 100ms, assume that it won't happen\n // This may not be accurate, but hopefully it won't take so much time\n // In Chrome, navigation seems to happen instantly in next microtask\n // But on Firefox, it seems to take much longer, around 50ms from our testing\n // We're using a hacky timeout since there doesn't seem to be way to know for sure\n const timer = setTimeout(() => {\n const index = pending.findIndex((it) => it.ref === done);\n\n if (index > -1) {\n pending[index].cb();\n pending.splice(index, 1);\n }\n }, 100);\n\n const onPopState = () => {\n const id = window.history.state?.id;\n const currentIndex = items.findIndex((item) => item.id === id);\n\n // Fix createMemoryHistory.index variable's value\n // as it may go out of sync when navigating in the browser.\n index = Math.max(currentIndex, 0);\n\n const last = pending.pop();\n\n window.removeEventListener('popstate', onPopState);\n last?.cb();\n };\n\n window.addEventListener('popstate', onPopState);\n window.history.go(n);\n });\n },\n\n // The `popstate` event is triggered when history changes, except `pushState` and `replaceState`\n // If we call `history.go(n)` ourselves, we don't want it to trigger the listener\n // Here we normalize it so that only external changes (e.g. user pressing back/forward) trigger the listener\n listen(listener: () => void) {\n const onPopState = () => {\n if (pending.length) {\n // This was triggered by `history.go(n)`, we shouldn't call the listener\n return;\n }\n\n listener();\n };\n\n window.addEventListener('popstate', onPopState);\n\n return () => window.removeEventListener('popstate', onPopState);\n },\n };\n\n return history;\n}\n"]}
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  var _exportNames = {
7
7
  Link: true,
8
+ LinkingContext: true,
8
9
  NavigationContainer: true,
9
10
  ServerContainer: true,
10
11
  DarkTheme: true,
@@ -34,6 +35,12 @@ Object.defineProperty(exports, "Link", {
34
35
  return _Link.default;
35
36
  }
36
37
  });
38
+ Object.defineProperty(exports, "LinkingContext", {
39
+ enumerable: true,
40
+ get: function () {
41
+ return _LinkingContext.default;
42
+ }
43
+ });
37
44
  Object.defineProperty(exports, "NavigationContainer", {
38
45
  enumerable: true,
39
46
  get: function () {
@@ -85,6 +92,8 @@ Object.defineProperty(exports, "useTheme", {
85
92
 
86
93
  var _Link = _interopRequireDefault(require("./Link"));
87
94
 
95
+ var _LinkingContext = _interopRequireDefault(require("./LinkingContext"));
96
+
88
97
  var _NavigationContainer = _interopRequireDefault(require("./NavigationContainer"));
89
98
 
90
99
  var _ServerContainer = _interopRequireDefault(require("./ServerContainer"));
@@ -1 +1 @@
1
- {"version":3,"sources":["index.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;AACA;;AACA;;AACA;;AACA;;AACA;;AACA;;AACA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AACA;;AACA;;AACA;;AACA;;AACA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA","sourcesContent":["export { default as Link } from './Link';\nexport { default as NavigationContainer } from './NavigationContainer';\nexport { default as ServerContainer } from './ServerContainer';\nexport { default as DarkTheme } from './theming/DarkTheme';\nexport { default as DefaultTheme } from './theming/DefaultTheme';\nexport { default as ThemeProvider } from './theming/ThemeProvider';\nexport { default as useTheme } from './theming/useTheme';\nexport * from './types';\nexport { default as useLinkBuilder } from './useLinkBuilder';\nexport { default as useLinkProps } from './useLinkProps';\nexport { default as useLinkTo } from './useLinkTo';\nexport { default as useScrollToTop } from './useScrollToTop';\nexport * from '@react-navigation/core';\n"]}
1
+ {"version":3,"sources":["index.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;AACA;;AACA;;AACA;;AACA;;AACA;;AACA;;AACA;;AACA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AACA;;AACA;;AACA;;AACA;;AACA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA","sourcesContent":["export { default as Link } from './Link';\nexport { default as LinkingContext } from './LinkingContext';\nexport { default as NavigationContainer } from './NavigationContainer';\nexport { default as ServerContainer } from './ServerContainer';\nexport { default as DarkTheme } from './theming/DarkTheme';\nexport { default as DefaultTheme } from './theming/DefaultTheme';\nexport { default as ThemeProvider } from './theming/ThemeProvider';\nexport { default as useTheme } from './theming/useTheme';\nexport * from './types';\nexport { default as useLinkBuilder } from './useLinkBuilder';\nexport { default as useLinkProps } from './useLinkProps';\nexport { default as useLinkTo } from './useLinkTo';\nexport { default as useScrollToTop } from './useScrollToTop';\nexport * from '@react-navigation/core';\n"]}
@@ -9,10 +9,10 @@ var _core = require("@react-navigation/core");
9
9
 
10
10
  var _fastDeepEqual = _interopRequireDefault(require("fast-deep-equal"));
11
11
 
12
- var _nonSecure = require("nanoid/non-secure");
13
-
14
12
  var React = _interopRequireWildcard(require("react"));
15
13
 
14
+ var _createMemoryHistory = _interopRequireDefault(require("./createMemoryHistory"));
15
+
16
16
  var _ServerContext = _interopRequireDefault(require("./ServerContext"));
17
17
 
18
18
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
@@ -21,229 +21,10 @@ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj &&
21
21
 
22
22
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
23
23
 
24
- const createMemoryHistory = () => {
25
- let index = 0;
26
- let items = []; // Pending callbacks for `history.go(n)`
27
- // We might modify the callback stored if it was interrupted, so we have a ref to identify it
28
-
29
- const pending = [];
30
-
31
- const interrupt = () => {
32
- // If another history operation was performed we need to interrupt existing ones
33
- // This makes sure that calls such as `history.replace` after `history.go` don't happen
34
- // Since otherwise it won't be correct if something else has changed
35
- pending.forEach(it => {
36
- const cb = it.cb;
37
-
38
- it.cb = () => cb(true);
39
- });
40
- };
41
-
42
- const history = {
43
- get index() {
44
- var _window$history$state;
45
-
46
- // We store an id in the state instead of an index
47
- // Index could get out of sync with in-memory values if page reloads
48
- const id = (_window$history$state = window.history.state) === null || _window$history$state === void 0 ? void 0 : _window$history$state.id;
49
-
50
- if (id) {
51
- const index = items.findIndex(item => item.id === id);
52
- return index > -1 ? index : 0;
53
- }
54
-
55
- return 0;
56
- },
57
-
58
- get(index) {
59
- return items[index];
60
- },
61
-
62
- backIndex(_ref) {
63
- let {
64
- path
65
- } = _ref;
66
-
67
- // We need to find the index from the element before current to get closest path to go back to
68
- for (let i = index - 1; i >= 0; i--) {
69
- const item = items[i];
70
-
71
- if (item.path === path) {
72
- return i;
73
- }
74
- }
75
-
76
- return -1;
77
- },
78
-
79
- push(_ref2) {
80
- let {
81
- path,
82
- state
83
- } = _ref2;
84
- interrupt();
85
- const id = (0, _nonSecure.nanoid)(); // When a new entry is pushed, all the existing entries after index will be inaccessible
86
- // So we remove any existing entries after the current index to clean them up
87
-
88
- items = items.slice(0, index + 1);
89
- items.push({
90
- path,
91
- state,
92
- id
93
- });
94
- index = items.length - 1; // We pass empty string for title because it's ignored in all browsers except safari
95
- // We don't store state object in history.state because:
96
- // - browsers have limits on how big it can be, and we don't control the size
97
- // - while not recommended, there could be non-serializable data in state
98
-
99
- window.history.pushState({
100
- id
101
- }, '', path);
102
- },
103
-
104
- replace(_ref3) {
105
- var _window$history$state2, _window$history$state3;
106
-
107
- let {
108
- path,
109
- state
110
- } = _ref3;
111
- interrupt();
112
- const id = (_window$history$state2 = (_window$history$state3 = window.history.state) === null || _window$history$state3 === void 0 ? void 0 : _window$history$state3.id) !== null && _window$history$state2 !== void 0 ? _window$history$state2 : (0, _nonSecure.nanoid)();
113
-
114
- if (!items.length || items.findIndex(item => item.id === id) < 0) {
115
- // There are two scenarios for creating an array with only one history record:
116
- // - When loaded id not found in the items array, this function by default will replace
117
- // the first item. We need to keep only the new updated object, otherwise it will break
118
- // the page when navigating forward in history.
119
- // - This is the first time any state modifications are done
120
- // So we need to push the entry as there's nothing to replace
121
- items = [{
122
- path,
123
- state,
124
- id
125
- }];
126
- index = 0;
127
- } else {
128
- items[index] = {
129
- path,
130
- state,
131
- id
132
- };
133
- }
134
-
135
- window.history.replaceState({
136
- id
137
- }, '', path);
138
- },
139
-
140
- // `history.go(n)` is asynchronous, there are couple of things to keep in mind:
141
- // - it won't do anything if we can't go `n` steps, the `popstate` event won't fire.
142
- // - each `history.go(n)` call will trigger a separate `popstate` event with correct location.
143
- // - the `popstate` event fires before the next frame after calling `history.go(n)`.
144
- // This method differs from `history.go(n)` in the sense that it'll go back as many steps it can.
145
- go(n) {
146
- interrupt();
147
-
148
- if (n === 0) {
149
- return;
150
- } // We shouldn't go back more than the 0 index (otherwise we'll exit the page)
151
- // Or forward more than the available index (or the app will crash)
152
-
153
-
154
- index = n < 0 ? Math.max(index - n, 0) : Math.min(index + n, items.length - 1); // When we call `history.go`, `popstate` will fire when there's history to go back to
155
- // So we need to somehow handle following cases:
156
- // - There's history to go back, `history.go` is called, and `popstate` fires
157
- // - `history.go` is called multiple times, we need to resolve on respective `popstate`
158
- // - No history to go back, but `history.go` was called, browser has no API to detect it
159
-
160
- return new Promise((resolve, reject) => {
161
- const done = interrupted => {
162
- clearTimeout(timer);
163
-
164
- if (interrupted) {
165
- reject(new Error('History was changed during navigation.'));
166
- return;
167
- } // There seems to be a bug in Chrome regarding updating the title
168
- // If we set a title just before calling `history.go`, the title gets lost
169
- // However the value of `document.title` is still what we set it to
170
- // It's just not displayed in the tab bar
171
- // To update the tab bar, we need to reset the title to something else first (e.g. '')
172
- // And set the title to what it was before so it gets applied
173
- // It won't work without setting it to empty string coz otherwise title isn't changing
174
- // Which means that the browser won't do anything after setting the title
175
-
176
-
177
- const {
178
- title
179
- } = window.document;
180
- window.document.title = '';
181
- window.document.title = title;
182
- resolve();
183
- };
184
-
185
- pending.push({
186
- ref: done,
187
- cb: done
188
- }); // If navigation didn't happen within 100ms, assume that it won't happen
189
- // This may not be accurate, but hopefully it won't take so much time
190
- // In Chrome, navigation seems to happen instantly in next microtask
191
- // But on Firefox, it seems to take much longer, around 50ms from our testing
192
- // We're using a hacky timeout since there doesn't seem to be way to know for sure
193
-
194
- const timer = setTimeout(() => {
195
- const index = pending.findIndex(it => it.ref === done);
196
-
197
- if (index > -1) {
198
- pending[index].cb();
199
- pending.splice(index, 1);
200
- }
201
- }, 100);
202
-
203
- const onPopState = () => {
204
- var _window$history$state4;
205
-
206
- const id = (_window$history$state4 = window.history.state) === null || _window$history$state4 === void 0 ? void 0 : _window$history$state4.id;
207
- const currentIndex = items.findIndex(item => item.id === id); // Fix createMemoryHistory.index variable's value
208
- // as it may go out of sync when navigating in the browser.
209
-
210
- index = Math.max(currentIndex, 0);
211
- const last = pending.pop();
212
- window.removeEventListener('popstate', onPopState);
213
- last === null || last === void 0 ? void 0 : last.cb();
214
- };
215
-
216
- window.addEventListener('popstate', onPopState);
217
- window.history.go(n);
218
- });
219
- },
220
-
221
- // The `popstate` event is triggered when history changes, except `pushState` and `replaceState`
222
- // If we call `history.go(n)` ourselves, we don't want it to trigger the listener
223
- // Here we normalize it so that only external changes (e.g. user pressing back/forward) trigger the listener
224
- listen(listener) {
225
- const onPopState = () => {
226
- if (pending.length) {
227
- // This was triggered by `history.go(n)`, we shouldn't call the listener
228
- return;
229
- }
230
-
231
- listener();
232
- };
233
-
234
- window.addEventListener('popstate', onPopState);
235
- return () => window.removeEventListener('popstate', onPopState);
236
- }
237
-
238
- };
239
- return history;
240
- };
241
24
  /**
242
25
  * Find the matching navigation state that changed between 2 navigation states
243
26
  * e.g.: a -> b -> c -> d and a -> b -> c -> e -> f, if history in b changed, b is the matching state
244
27
  */
245
-
246
-
247
28
  const findMatchingState = (a, b) => {
248
29
  if (a === undefined || b === undefined || a.key !== b.key) {
249
30
  return [undefined, undefined];
@@ -304,7 +85,7 @@ const series = cb => {
304
85
 
305
86
  let linkingHandlers = [];
306
87
 
307
- function useLinking(ref, _ref4) {
88
+ function useLinking(ref, _ref) {
308
89
  let {
309
90
  independent,
310
91
  enabled = true,
@@ -312,7 +93,7 @@ function useLinking(ref, _ref4) {
312
93
  getStateFromPath = _core.getStateFromPath,
313
94
  getPathFromState = _core.getPathFromState,
314
95
  getActionFromState = _core.getActionFromState
315
- } = _ref4;
96
+ } = _ref;
316
97
  React.useEffect(() => {
317
98
  if (process.env.NODE_ENV === 'production') {
318
99
  return undefined;
@@ -340,7 +121,7 @@ function useLinking(ref, _ref4) {
340
121
  }
341
122
  };
342
123
  }, [enabled, independent]);
343
- const [history] = React.useState(createMemoryHistory); // We store these options in ref to avoid re-creating getInitialState and re-subscribing listeners
124
+ const [history] = React.useState(_createMemoryHistory.default); // We store these options in ref to avoid re-creating getInitialState and re-subscribing listeners
344
125
  // This lets user avoid wrapping the items in `React.useCallback` or `React.useMemo`
345
126
  // Not re-creating `getInitialState` is important coz it makes it easier for the user to use in an effect
346
127