1import { getActionFromState, LinkingOptions } from '@react-navigation/native'; 2 3import { RouteNode } from './Route'; 4import { State } from './fork/getPathFromState'; 5import { getReactNavigationConfig, Screen } from './getReactNavigationConfig'; 6import { 7 addEventListener, 8 getInitialURL, 9 getPathFromState, 10 getStateFromPath, 11} from './link/linking'; 12 13export function getNavigationConfig(routes: RouteNode): { 14 initialRouteName?: string; 15 screens: Record<string, Screen>; 16} { 17 return getReactNavigationConfig(routes, true); 18} 19 20export type ExpoLinkingOptions = LinkingOptions<object> & { 21 getPathFromState?: typeof getPathFromState; 22}; 23 24export function getLinkingConfig(routes: RouteNode): ExpoLinkingOptions { 25 return { 26 prefixes: [], 27 // @ts-expect-error 28 config: getNavigationConfig(routes), 29 // A custom getInitialURL is used on native to ensure the app always starts at 30 // the root path if it's launched from something other than a deep link. 31 // This helps keep the native functionality working like the web functionality. 32 // For example, if you had a root navigator where the first screen was `/settings` and the second was `/index` 33 // then `/index` would be used on web and `/settings` would be used on native. 34 getInitialURL, 35 subscribe: addEventListener, 36 getStateFromPath: getStateFromPathMemoized, 37 getPathFromState(state: State, options: Parameters<typeof getPathFromState>[1]) { 38 return ( 39 getPathFromState(state, { 40 screens: [], 41 ...this.config, 42 ...options, 43 }) ?? '/' 44 ); 45 }, 46 // Add all functions to ensure the types never need to fallback. 47 // This is a convenience for usage in the package. 48 getActionFromState, 49 }; 50} 51 52export const stateCache = new Map<string, any>(); 53 54/** We can reduce work by memoizing the state by the pathname. This only works because the options (linking config) theoretically never change. */ 55function getStateFromPathMemoized(path: string, options: Parameters<typeof getStateFromPath>[1]) { 56 const cached = stateCache.get(path); 57 if (cached) { 58 return cached; 59 } 60 const result = getStateFromPath(path, options); 61 stateCache.set(path, result); 62 return result; 63} 64