@react-navigation/routers 8.0.0-alpha.6 → 8.0.0-alpha.8

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.
@@ -47,11 +47,12 @@ export const BaseRouter = {
47
47
  case 'RESET':
48
48
  {
49
49
  const nextState = action.payload;
50
- if (nextState.routes.length === 0 || nextState.routes.some(route => !state.routeNames.includes(route.name))) {
50
+ const routeNamesSet = new Set(state.routeNames);
51
+ if (nextState.routes.length === 0 || nextState.routes.some(route => !routeNamesSet.has(route.name))) {
51
52
  return null;
52
53
  }
53
54
  if (nextState.stale === false) {
54
- if (state.routeNames.length !== nextState.routeNames.length || nextState.routeNames.some(name => !state.routeNames.includes(name))) {
55
+ if (state.routeNames.length !== nextState.routeNames.length || nextState.routeNames.some(name => !routeNamesSet.has(name))) {
55
56
  return null;
56
57
  }
57
58
  return {
@@ -1 +1 @@
1
- {"version":3,"names":["nanoid","BaseRouter","getStateForAction","state","action","type","index","source","routes","findIndex","r","key","map","i","params","payload","history","nextState","length","some","route","routeNames","includes","name","stale","shouldActionChangeFocus"],"sourceRoot":"../../src","sources":["BaseRouter.tsx"],"mappings":";;AAAA,SAASA,MAAM,QAAQ,mBAAmB;AAQ1C;AACA;AACA;AACA;AACA,OAAO,MAAMC,UAAU,GAAG;EACxBC,iBAAiBA,CACfC,KAAY,EACZC,MAA8B,EACM;IACpC,QAAQA,MAAM,CAACC,IAAI;MACjB,KAAK,YAAY;MACjB,KAAK,gBAAgB;QAAE;UACrB,MAAMC,KAAK,GAAGF,MAAM,CAACG,MAAM,GACvBJ,KAAK,CAACK,MAAM,CAACC,SAAS,CAAEC,CAAC,IAAKA,CAAC,CAACC,GAAG,KAAKP,MAAM,CAACG,MAAM,CAAC,GACtDJ,KAAK,CAACG,KAAK;UAEf,IAAIA,KAAK,KAAK,CAAC,CAAC,EAAE;YAChB,OAAO,IAAI;UACb;UAEA,OAAO;YACL,GAAGH,KAAK;YACRK,MAAM,EAAEL,KAAK,CAACK,MAAM,CAACI,GAAG,CAAC,CAACF,CAAC,EAAEG,CAAC,KAC5BA,CAAC,KAAKP,KAAK,GACP;cACE,GAAGI,CAAC;cACJI,MAAM,EACJV,MAAM,CAACC,IAAI,KAAK,gBAAgB,GAC5BD,MAAM,CAACW,OAAO,CAACD,MAAM,GACrB;gBAAE,GAAGJ,CAAC,CAACI,MAAM;gBAAE,GAAGV,MAAM,CAACW,OAAO,CAACD;cAAO;YAChD,CAAC,GACDJ,CACN;UACF,CAAC;QACH;MAEA,KAAK,aAAa;QAAE;UAClB,MAAMJ,KAAK,GAAGF,MAAM,CAACG,MAAM,GACvBJ,KAAK,CAACK,MAAM,CAACC,SAAS,CAAEC,CAAC,IAAKA,CAAC,CAACC,GAAG,KAAKP,MAAM,CAACG,MAAM,CAAC,GACtDJ,KAAK,CAACG,KAAK;UAEf,IAAIA,KAAK,KAAK,CAAC,CAAC,EAAE;YAChB,OAAO,IAAI;UACb;UAEA,OAAO;YACL,GAAGH,KAAK;YACRK,MAAM,EAAEL,KAAK,CAACK,MAAM,CAACI,GAAG,CAAC,CAACF,CAAC,EAAEG,CAAC,KAC5BA,CAAC,KAAKP,KAAK,GACP;cACE,GAAGI,CAAC;cACJI,MAAM,EAAEV,MAAM,CAACW,OAAO,CAACD,MAAM;cAC7BE,OAAO,EAAE,CACP,IAAIN,CAAC,CAACM,OAAO,IAAI,EAAE,CAAC,EACpB;gBAAEX,IAAI,EAAE,QAAQ;gBAAES,MAAM,EAAEJ,CAAC,CAACI;cAAO,CAAC;YAExC,CAAC,GACDJ,CACN;UACF,CAAC;QACH;MAEA,KAAK,OAAO;QAAE;UACZ,MAAMO,SAAS,GAAGb,MAAM,CAACW,OAAsC;UAE/D,IACEE,SAAS,CAACT,MAAM,CAACU,MAAM,KAAK,CAAC,IAC7BD,SAAS,CAACT,MAAM,CAACW,IAAI,CAClBC,KAAuB,IAAK,CAACjB,KAAK,CAACkB,UAAU,CAACC,QAAQ,CAACF,KAAK,CAACG,IAAI,CACpE,CAAC,EACD;YACA,OAAO,IAAI;UACb;UAEA,IAAIN,SAAS,CAACO,KAAK,KAAK,KAAK,EAAE;YAC7B,IACErB,KAAK,CAACkB,UAAU,CAACH,MAAM,KAAKD,SAAS,CAACI,UAAU,CAACH,MAAM,IACvDD,SAAS,CAACI,UAAU,CAACF,IAAI,CACtBI,IAAI,IAAK,CAACpB,KAAK,CAACkB,UAAU,CAACC,QAAQ,CAACC,IAAI,CAC3C,CAAC,EACD;cACA,OAAO,IAAI;YACb;YAEA,OAAO;cACL,GAAGN,SAAS;cACZT,MAAM,EAAES,SAAS,CAACT,MAAM,CAACI,GAAG,CAAEQ,KAAK,IACjCA,KAAK,CAACT,GAAG,GAAGS,KAAK,GAAG;gBAAE,GAAGA,KAAK;gBAAET,GAAG,EAAE,GAAGS,KAAK,CAACG,IAAI,IAAIvB,MAAM,CAAC,CAAC;cAAG,CACnE;YACF,CAAC;UACH;UAEA,OAAOiB,SAAS;QAClB;MAEA;QACE,OAAO,IAAI;IACf;EACF,CAAC;EAEDQ,uBAAuBA,CAACrB,MAA8B,EAAE;IACtD,OAAOA,MAAM,CAACC,IAAI,KAAK,UAAU;EACnC;AACF,CAAC","ignoreList":[]}
1
+ {"version":3,"names":["nanoid","BaseRouter","getStateForAction","state","action","type","index","source","routes","findIndex","r","key","map","i","params","payload","history","nextState","routeNamesSet","Set","routeNames","length","some","route","has","name","stale","shouldActionChangeFocus"],"sourceRoot":"../../src","sources":["BaseRouter.tsx"],"mappings":"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","ignoreList":[]}
@@ -61,16 +61,34 @@ function retainRoutes(previousState, nextState) {
61
61
  }
62
62
  const retainedRouteKeySet = new Set(nextState.retainedRouteKeys);
63
63
  const nextRouteKeySet = new Set(nextState.routes.map(route => route.key));
64
- const retainedRoutes = previousState.routes.filter(route => retainedRouteKeySet.has(route.key) && !nextRouteKeySet.has(route.key));
64
+ const retainedRoutes = getActiveRoutes(previousState).filter(route => retainedRouteKeySet.has(route.key) && !nextRouteKeySet.has(route.key));
65
65
  if (!retainedRoutes.length) {
66
66
  return nextState;
67
67
  }
68
68
  const removedRetainedRouteKeys = new Set(retainedRoutes.map(route => route.key));
69
+ return getStateWithRoutes(nextState, getActiveRoutes(nextState), getPreloadedRoutes(nextState), retainedRoutes.concat(getRetainedRoutes(nextState).filter(route => !removedRetainedRouteKeys.has(route.key))));
70
+ }
71
+ const getActiveRoutes = state => state.routes.slice(0, state.index + 1);
72
+ const getInactiveRoutes = state => state.routes.slice(state.index + 1);
73
+ const getPreloadedRoutes = state => {
74
+ const retainedRouteKeySet = new Set(state.retainedRouteKeys);
75
+ return getInactiveRoutes(state).filter(route => !retainedRouteKeySet.has(route.key));
76
+ };
77
+ const getRetainedRoutes = state => {
78
+ const retainedRouteKeySet = new Set(state.retainedRouteKeys);
79
+ return getInactiveRoutes(state).filter(route => retainedRouteKeySet.has(route.key));
80
+ };
81
+ const getStateWithRoutes = (state, activeRoutes, preloadedRoutes = getPreloadedRoutes(state), retainedRoutes = getRetainedRoutes(state)) => {
82
+ const routeKeySet = new Set(activeRoutes.map(route => route.key));
83
+ const retainedRouteKeySet = new Set(state.retainedRouteKeys);
84
+ const filteredRetainedRoutes = retainedRoutes.filter(route => !routeKeySet.has(route.key));
85
+ const filteredPreloadedRoutes = preloadedRoutes.filter(route => !retainedRouteKeySet.has(route.key) && !routeKeySet.has(route.key));
69
86
  return {
70
- ...nextState,
71
- preloadedRoutes: retainedRoutes.concat(nextState.preloadedRoutes.filter(route => !removedRetainedRouteKeys.has(route.key)))
87
+ ...state,
88
+ index: activeRoutes.length - 1,
89
+ routes: activeRoutes.concat(filteredRetainedRoutes, filteredPreloadedRoutes)
72
90
  };
73
- }
91
+ };
74
92
  export function StackRouter(options) {
75
93
  const router = {
76
94
  ...BaseRouter,
@@ -86,7 +104,6 @@ export function StackRouter(options) {
86
104
  key: `stack-${nanoid()}`,
87
105
  index: 0,
88
106
  routeNames,
89
- preloadedRoutes: [],
90
107
  retainedRouteKeys: [],
91
108
  routes: [{
92
109
  key: `${initialRouteName}-${nanoid()}`,
@@ -111,15 +128,6 @@ export function StackRouter(options) {
111
128
  ...route.params
112
129
  } : route.params
113
130
  }));
114
- const preloadedRoutes = state.preloadedRoutes?.filter(route => routeNames.includes(route.name)).map(route => ({
115
- ...route,
116
- key: route.key || `${route.name}-${nanoid()}`,
117
- params: routeParamList[route.name] !== undefined ? {
118
- ...routeParamList[route.name],
119
- ...route.params
120
- } : route.params
121
- })) ?? [];
122
- const retainedRouteKeys = state.retainedRouteKeys?.filter(key => [...routes, ...preloadedRoutes].some(route => route.key === key)) ?? [];
123
131
  if (routes.length === 0) {
124
132
  const initialRouteName = options.initialRouteName !== undefined ? options.initialRouteName : routeNames[0];
125
133
  routes.push({
@@ -128,14 +136,16 @@ export function StackRouter(options) {
128
136
  params: routeParamList[initialRouteName]
129
137
  });
130
138
  }
139
+ const index = Math.min(Math.max(state.index ?? routes.length - 1, 0), routes.length - 1);
140
+ const routeKeys = new Set(routes.map(route => route.key));
141
+ const retainedRouteKeys = state.retainedRouteKeys?.filter(key => routeKeys.has(key)) ?? [];
131
142
  return {
132
143
  stale: false,
133
144
  type: 'stack',
134
145
  key: `stack-${nanoid()}`,
135
- index: routes.length - 1,
146
+ index,
136
147
  routeNames,
137
148
  routes,
138
- preloadedRoutes,
139
149
  retainedRouteKeys
140
150
  };
141
151
  },
@@ -144,8 +154,9 @@ export function StackRouter(options) {
144
154
  routeParamList,
145
155
  routeKeyChanges
146
156
  }) {
147
- const routes = state.routes.filter(route => routeNames.includes(route.name) && !routeKeyChanges.includes(route.name));
148
- const preloadedRoutes = state.preloadedRoutes.filter(route => routeNames.includes(route.name) && !routeKeyChanges.includes(route.name));
157
+ const routes = getActiveRoutes(state).filter(route => routeNames.includes(route.name) && !routeKeyChanges.includes(route.name));
158
+ const preloadedRoutes = getPreloadedRoutes(state).filter(route => routeNames.includes(route.name) && !routeKeyChanges.includes(route.name));
159
+ const retainedRoutes = getRetainedRoutes(state).filter(route => routeNames.includes(route.name) && !routeKeyChanges.includes(route.name));
149
160
  if (routes.length === 0) {
150
161
  const initialRouteName = options.initialRouteName !== undefined && routeNames.includes(options.initialRouteName) ? options.initialRouteName : routeNames[0];
151
162
  routes.push({
@@ -154,36 +165,33 @@ export function StackRouter(options) {
154
165
  params: routeParamList[initialRouteName]
155
166
  });
156
167
  }
157
- const routeKeys = new Set([...routes, ...preloadedRoutes].map(route => route.key));
168
+ const routeKeys = new Set([...routes, ...preloadedRoutes, ...retainedRoutes].map(route => route.key));
158
169
  const retainedRouteKeys = state.retainedRouteKeys.filter(key => routeKeys.has(key));
159
- return {
170
+ return getStateWithRoutes({
160
171
  ...state,
161
172
  routeNames,
162
- routes,
163
- preloadedRoutes,
164
- retainedRouteKeys,
165
- index: Math.min(state.index, routes.length - 1)
166
- };
173
+ retainedRouteKeys
174
+ }, routes, preloadedRoutes, retainedRoutes);
167
175
  },
168
176
  getStateForRouteFocus(state, key) {
169
- const index = state.routes.findIndex(r => r.key === key);
177
+ const routes = getActiveRoutes(state);
178
+ const index = routes.findIndex(r => r.key === key);
170
179
  if (index === -1 || index === state.index) {
171
180
  return state;
172
181
  }
173
- return retainRoutes(state, {
174
- ...state,
175
- index,
176
- routes: state.routes.slice(0, index + 1)
177
- });
182
+ return retainRoutes(state, getStateWithRoutes(state, routes.slice(0, index + 1)));
178
183
  },
179
184
  getStateForAction(state, action, options) {
180
185
  const {
181
186
  routeParamList
182
187
  } = options;
188
+ const routes = getActiveRoutes(state);
189
+ const preloadedRoutes = getPreloadedRoutes(state);
190
+ const inactiveRoutes = getInactiveRoutes(state);
183
191
  switch (action.type) {
184
192
  case 'REPLACE':
185
193
  {
186
- const currentIndex = action.target === state.key && action.source ? state.routes.findIndex(r => r.key === action.source) : state.index;
194
+ const currentIndex = action.target === state.key && action.source ? routes.findIndex(r => r.key === action.source) : state.index;
187
195
  if (currentIndex === -1) {
188
196
  return null;
189
197
  }
@@ -195,8 +203,8 @@ export function StackRouter(options) {
195
203
  params: action.payload.params
196
204
  });
197
205
 
198
- // Re-use preloaded route if available
199
- let route = state.preloadedRoutes.find(route => route.name === action.payload.name && id === getId?.({
206
+ // Re-use inactive route if available
207
+ let route = inactiveRoutes.find(route => route.name === action.payload.name && id === getId?.({
200
208
  params: route.params
201
209
  }));
202
210
  if (!route) {
@@ -204,12 +212,19 @@ export function StackRouter(options) {
204
212
  action,
205
213
  routeParamList
206
214
  });
215
+ } else {
216
+ const params = createParamsFromAction({
217
+ action,
218
+ routeParamList
219
+ });
220
+ if (route.params !== params) {
221
+ route = {
222
+ ...route,
223
+ params
224
+ };
225
+ }
207
226
  }
208
- return retainRoutes(state, {
209
- ...state,
210
- routes: state.routes.map((r, i) => i === currentIndex ? route : r),
211
- preloadedRoutes: state.preloadedRoutes.filter(r => r.key !== route.key)
212
- });
227
+ return retainRoutes(state, getStateWithRoutes(state, routes.map((r, i) => i === currentIndex ? route : r), preloadedRoutes.filter(r => r.key !== route.key)));
213
228
  }
214
229
  case 'PUSH':
215
230
  case 'NAVIGATE':
@@ -223,15 +238,15 @@ export function StackRouter(options) {
223
238
  });
224
239
  let route;
225
240
  if (action.type === 'NAVIGATE') {
226
- const currentRoute = state.routes[state.index];
241
+ const currentRoute = routes[state.index];
227
242
  if (id !== undefined) {
228
243
  if (currentRoute.name === action.payload.name && id === getId?.({
229
244
  params: currentRoute.params
230
245
  })) {
231
246
  route = currentRoute;
232
247
  } else if (action.payload.pop) {
233
- for (let i = state.routes.length - 1; i >= 0; i--) {
234
- const r = state.routes[i];
248
+ for (let i = routes.length - 1; i >= 0; i--) {
249
+ const r = routes[i];
235
250
  if (r.name !== action.payload.name) {
236
251
  continue;
237
252
  }
@@ -265,12 +280,12 @@ export function StackRouter(options) {
265
280
  if (action.payload.name === currentRoute.name) {
266
281
  route = currentRoute;
267
282
  } else if (action.payload.pop) {
268
- route = state.routes.findLast(route => route.name === action.payload.name);
283
+ route = routes.findLast(route => route.name === action.payload.name);
269
284
  }
270
285
  }
271
286
  }
272
287
  if (!route) {
273
- route = state.preloadedRoutes.find(route => route.name === action.payload.name && id === getId?.({
288
+ route = inactiveRoutes.find(route => route.name === action.payload.name && id === getId?.({
274
289
  params: route.params
275
290
  }));
276
291
  }
@@ -287,50 +302,55 @@ export function StackRouter(options) {
287
302
  routeParamList
288
303
  });
289
304
  }
290
- let routes;
305
+ let nextRoutes;
291
306
  if (route) {
292
307
  if (action.type === 'NAVIGATE' && action.payload.pop) {
293
- routes = [];
308
+ nextRoutes = [];
294
309
 
295
310
  // Get all routes until the matching one
296
- for (const r of state.routes) {
311
+ for (const r of routes) {
297
312
  if (r.key === route.key) {
298
- routes.push({
313
+ nextRoutes.push({
299
314
  ...route,
300
315
  path: action.payload.path !== undefined ? action.payload.path : route.path,
301
316
  params
302
317
  });
303
318
  break;
304
319
  }
305
- routes.push(r);
320
+ nextRoutes.push(r);
321
+ }
322
+ if (!nextRoutes.some(r => r.key === route.key)) {
323
+ nextRoutes.push({
324
+ ...route,
325
+ path: action.payload.path !== undefined ? action.payload.path : route.path,
326
+ params
327
+ });
306
328
  }
307
329
  } else {
308
- routes = state.routes.filter(r => r.key !== route.key);
309
- routes.push({
330
+ nextRoutes = routes.filter(r => r.key !== route.key);
331
+ nextRoutes.push({
310
332
  ...route,
311
333
  path: action.type === 'NAVIGATE' && action.payload.path !== undefined ? action.payload.path : route.path,
312
334
  params
313
335
  });
314
336
  }
315
337
  } else {
316
- routes = [...state.routes, {
338
+ nextRoutes = [...routes, {
317
339
  key: `${action.payload.name}-${nanoid()}`,
318
340
  name: action.payload.name,
319
341
  path: action.type === 'NAVIGATE' ? action.payload.path : undefined,
320
342
  params
321
343
  }];
322
344
  }
323
- return retainRoutes(state, {
324
- ...state,
325
- index: routes.length - 1,
326
- preloadedRoutes: state.preloadedRoutes.filter(route => routes[routes.length - 1].key !== route.key),
327
- routes
328
- });
345
+ return retainRoutes(state, getStateWithRoutes(state, nextRoutes, preloadedRoutes.filter(route => nextRoutes[nextRoutes.length - 1].key !== route.key)));
329
346
  }
330
347
  case 'POP':
331
348
  {
332
- let currentIndex = action.target === state.key && action.source ? state.routes.findIndex(r => r.key === action.source) : state.index;
333
- let route = state.routes[currentIndex];
349
+ let currentIndex = action.target === state.key && action.source ? routes.findIndex(r => r.key === action.source) : state.index;
350
+ if (currentIndex === -1) {
351
+ return null;
352
+ }
353
+ let route = routes[currentIndex];
334
354
 
335
355
  /**
336
356
  * When popping entries,
@@ -343,42 +363,38 @@ export function StackRouter(options) {
343
363
  */
344
364
  if (route.history?.length || currentIndex > 0) {
345
365
  let count = action.payload.count;
346
- let routes = state.routes;
366
+ let nextRoutes = routes;
347
367
  while (count > 0 && (route.history?.length || currentIndex > 0)) {
348
368
  if (route.history?.length) {
349
- routes = [...routes];
369
+ nextRoutes = [...nextRoutes];
350
370
  const end = Math.min(count, route.history.length);
351
371
  const last = route.history.at(-end);
352
372
  const history = route.history.slice(0, -end);
353
373
  const removed = route.history.length - history.length;
354
374
  count = count - removed;
355
- routes[currentIndex] = {
375
+ nextRoutes[currentIndex] = {
356
376
  ...route,
357
377
  params: last?.type === 'params' ? last.params : route.params,
358
378
  history
359
379
  };
360
380
  }
361
381
  if (currentIndex > 0 && count > 0) {
362
- const length = routes.length;
382
+ const length = nextRoutes.length;
363
383
  const end = Math.max(currentIndex - count + 1, 1);
364
- routes = routes.slice(0, end).concat(routes.slice(currentIndex + 1));
365
- const removed = length - routes.length;
384
+ nextRoutes = nextRoutes.slice(0, end).concat(nextRoutes.slice(currentIndex + 1));
385
+ const removed = length - nextRoutes.length;
366
386
  count = count - removed;
367
- currentIndex = routes.length - 1;
368
- route = routes[currentIndex];
387
+ currentIndex = nextRoutes.length - 1;
388
+ route = nextRoutes[currentIndex];
369
389
  }
370
390
  }
371
- return retainRoutes(state, {
372
- ...state,
373
- index: routes.length - 1,
374
- routes
375
- });
391
+ return retainRoutes(state, getStateWithRoutes(state, nextRoutes));
376
392
  }
377
393
  return null;
378
394
  }
379
395
  case 'POP_TO_TOP':
380
396
  {
381
- let route = state.routes[0];
397
+ let route = routes[0];
382
398
  if (state.index > 0 || route.history?.length) {
383
399
  if (route.history?.length) {
384
400
  route = {
@@ -386,17 +402,13 @@ export function StackRouter(options) {
386
402
  history: undefined
387
403
  };
388
404
  }
389
- return retainRoutes(state, {
390
- ...state,
391
- index: 0,
392
- routes: [route]
393
- });
405
+ return retainRoutes(state, getStateWithRoutes(state, [route]));
394
406
  }
395
407
  return null;
396
408
  }
397
409
  case 'POP_TO':
398
410
  {
399
- const currentIndex = action.target === state.key && action.source ? state.routes.findLastIndex(r => r.key === action.source) : state.index;
411
+ const currentIndex = action.target === state.key && action.source ? routes.findLastIndex(r => r.key === action.source) : state.index;
400
412
  if (currentIndex === -1) {
401
413
  return null;
402
414
  }
@@ -413,7 +425,7 @@ export function StackRouter(options) {
413
425
  });
414
426
  if (id !== undefined) {
415
427
  for (let i = currentIndex; i >= 0; i--) {
416
- const r = state.routes[i];
428
+ const r = routes[i];
417
429
  if (r.name !== action.payload.name) {
418
430
  continue;
419
431
  }
@@ -438,11 +450,11 @@ export function StackRouter(options) {
438
450
  }
439
451
  }
440
452
  }
441
- } else if (state.routes[currentIndex].name === action.payload.name) {
453
+ } else if (routes[currentIndex].name === action.payload.name) {
442
454
  index = currentIndex;
443
455
  } else {
444
456
  for (let i = currentIndex; i >= 0; i--) {
445
- if (state.routes[i].name === action.payload.name) {
457
+ if (routes[i].name === action.payload.name) {
446
458
  index = i;
447
459
  break;
448
460
  }
@@ -451,8 +463,8 @@ export function StackRouter(options) {
451
463
 
452
464
  // If the route doesn't exist, remove the current route and add the new one
453
465
  if (index === -1) {
454
- // Re-use preloaded route if available
455
- let route = state.preloadedRoutes.find(route => route.name === action.payload.name && id === getId?.({
466
+ // Re-use inactive route if available
467
+ let route = inactiveRoutes.find(route => route.name === action.payload.name && id === getId?.({
456
468
  params: route.params
457
469
  }));
458
470
  if (!route) {
@@ -460,16 +472,22 @@ export function StackRouter(options) {
460
472
  action,
461
473
  routeParamList
462
474
  });
475
+ } else {
476
+ const params = createParamsFromAction({
477
+ action,
478
+ routeParamList
479
+ });
480
+ if (route.params !== params) {
481
+ route = {
482
+ ...route,
483
+ params
484
+ };
485
+ }
463
486
  }
464
- const routes = state.routes.slice(0, currentIndex).concat(route);
465
- return retainRoutes(state, {
466
- ...state,
467
- index: routes.length - 1,
468
- routes,
469
- preloadedRoutes: state.preloadedRoutes.filter(r => r.key !== route.key)
470
- });
487
+ const nextRoutes = routes.slice(0, currentIndex).concat(route);
488
+ return retainRoutes(state, getStateWithRoutes(state, nextRoutes, preloadedRoutes.filter(r => r.key !== route.key)));
471
489
  }
472
- const route = state.routes[index];
490
+ const route = routes[index];
473
491
  let baseParams = route.params;
474
492
  let history = route.history;
475
493
  if (historyIndex !== undefined && route.history) {
@@ -489,18 +507,14 @@ export function StackRouter(options) {
489
507
  routeParamList
490
508
  });
491
509
  }
492
- return retainRoutes(state, {
493
- ...state,
494
- index,
495
- routes: [...state.routes.slice(0, index), params !== baseParams || historyIndex !== undefined ? {
496
- ...route,
497
- params,
498
- history
499
- } : state.routes[index]]
500
- });
510
+ return retainRoutes(state, getStateWithRoutes(state, [...routes.slice(0, index), params !== baseParams || historyIndex !== undefined ? {
511
+ ...route,
512
+ params,
513
+ history
514
+ } : routes[index]]));
501
515
  }
502
516
  case 'GO_BACK':
503
- if (state.index > 0 || state.routes[state.index].history?.length) {
517
+ if (state.index > 0 || routes[state.index].history?.length) {
504
518
  return router.getStateForAction(state, {
505
519
  type: 'POP',
506
520
  payload: {
@@ -513,8 +527,8 @@ export function StackRouter(options) {
513
527
  return null;
514
528
  case 'RETAIN':
515
529
  {
516
- const routeKey = action.source ?? state.routes[state.index].key;
517
- if (!state.routes.some(route => route.key === routeKey) && !state.preloadedRoutes.some(route => route.key === routeKey)) {
530
+ const routeKey = action.source ?? routes[state.index].key;
531
+ if (!state.routes.some(route => route.key === routeKey)) {
518
532
  return null;
519
533
  }
520
534
  if (action.payload.enable) {
@@ -529,14 +543,16 @@ export function StackRouter(options) {
529
543
  if (!state.retainedRouteKeys.includes(routeKey)) {
530
544
  return state;
531
545
  }
532
- return {
546
+ return getStateWithRoutes({
533
547
  ...state,
534
- preloadedRoutes: state.preloadedRoutes.filter(route => route.key !== routeKey),
535
548
  retainedRouteKeys: state.retainedRouteKeys.filter(key => key !== routeKey)
536
- };
549
+ }, routes, preloadedRoutes.filter(route => route.key !== routeKey));
537
550
  }
538
551
  case 'PRELOAD':
539
552
  {
553
+ if (!state.routeNames.includes(action.payload.name)) {
554
+ return null;
555
+ }
540
556
  const getId = options.routeGetIdList[action.payload.name];
541
557
  const id = getId?.({
542
558
  params: action.payload.params
@@ -547,53 +563,41 @@ export function StackRouter(options) {
547
563
  });
548
564
  let route;
549
565
  if (action.payload.reuse) {
550
- route = state.preloadedRoutes.findLast(route => route.name === action.payload.name && (id === undefined || id === getId?.({
566
+ route = preloadedRoutes.findLast(route => route.name === action.payload.name && (id === undefined || id === getId?.({
551
567
  params: route.params
552
568
  })));
553
569
  if (route) {
554
- return {
555
- ...state,
556
- preloadedRoutes: state.preloadedRoutes.map(r => r.key === route?.key && r.params !== params ? {
557
- ...r,
558
- params
559
- } : r)
560
- };
570
+ return getStateWithRoutes(state, routes, preloadedRoutes.map(r => r.key === route?.key && r.params !== params ? {
571
+ ...r,
572
+ params
573
+ } : r));
561
574
  }
562
575
  }
563
576
  if (id !== undefined) {
564
- route = state.routes.findLast(route => route.name === action.payload.name && id === getId?.({
577
+ route = routes.findLast(route => route.name === action.payload.name && id === getId?.({
565
578
  params: route.params
566
579
  }));
567
580
  } else if (action.payload.reuse) {
568
- route = state.routes.findLast(route => route.name === action.payload.name);
581
+ route = routes.findLast(route => route.name === action.payload.name);
569
582
  }
570
583
  if (route) {
571
- return {
572
- ...state,
573
- routes: state.routes.map(r => r.key === route.key && r.params !== params ? {
574
- ...r,
575
- params
576
- } : r)
577
- };
584
+ return getStateWithRoutes(state, routes.map(r => r.key === route.key && r.params !== params ? {
585
+ ...r,
586
+ params
587
+ } : r), preloadedRoutes);
578
588
  } else {
579
- return {
580
- ...state,
581
- preloadedRoutes: state.preloadedRoutes.filter(r => r.name !== action.payload.name || id !== getId?.({
582
- params: r.params
583
- })).concat(createRouteFromAction({
584
- action,
585
- routeParamList
586
- }))
587
- };
589
+ return getStateWithRoutes(state, routes, preloadedRoutes.filter(r => r.name !== action.payload.name || id !== getId?.({
590
+ params: r.params
591
+ })).concat(createRouteFromAction({
592
+ action,
593
+ routeParamList
594
+ })));
588
595
  }
589
596
  }
590
597
  default:
591
598
  return BaseRouter.getStateForAction(state, action);
592
599
  }
593
600
  },
594
- getRoutesFromState(state) {
595
- return [...state.routes, ...state.preloadedRoutes];
596
- },
597
601
  actionCreators: StackActions
598
602
  };
599
603
  return router;