expo-router 3.1.2 → 3.3.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 (168) hide show
  1. package/_ctx.android.js +1 -1
  2. package/_ctx.ios.js +1 -1
  3. package/_ctx.web.js +1 -1
  4. package/babel.js +1 -209
  5. package/build/ExpoRoot.d.ts.map +1 -1
  6. package/build/ExpoRoot.js +57 -15
  7. package/build/ExpoRoot.js.map +1 -1
  8. package/build/LocationProvider.d.ts +3 -2
  9. package/build/LocationProvider.d.ts.map +1 -1
  10. package/build/LocationProvider.js +31 -7
  11. package/build/LocationProvider.js.map +1 -1
  12. package/build/Route.d.ts +3 -0
  13. package/build/Route.d.ts.map +1 -1
  14. package/build/Route.js +1 -1
  15. package/build/Route.js.map +1 -1
  16. package/build/fork/NavigationContainer.native.js +5 -3
  17. package/build/fork/NavigationContainer.native.js.map +1 -1
  18. package/build/fork/extractPathFromURL.d.ts.map +1 -1
  19. package/build/fork/extractPathFromURL.js +17 -16
  20. package/build/fork/extractPathFromURL.js.map +1 -1
  21. package/build/fork/getPathFromState.d.ts +1 -1
  22. package/build/fork/getPathFromState.d.ts.map +1 -1
  23. package/build/fork/getPathFromState.js +17 -38
  24. package/build/fork/getPathFromState.js.map +1 -1
  25. package/build/fork/getStateFromPath.d.ts +2 -2
  26. package/build/fork/getStateFromPath.d.ts.map +1 -1
  27. package/build/fork/getStateFromPath.js +71 -52
  28. package/build/fork/getStateFromPath.js.map +1 -1
  29. package/build/getDevServer/index.d.ts +0 -3
  30. package/build/getDevServer/index.d.ts.map +1 -1
  31. package/build/getDevServer/index.js +1 -28
  32. package/build/getDevServer/index.js.map +1 -1
  33. package/build/getReactNavigationConfig.d.ts.map +1 -1
  34. package/build/getReactNavigationConfig.js +3 -0
  35. package/build/getReactNavigationConfig.js.map +1 -1
  36. package/build/getRoutes.d.ts +8 -5
  37. package/build/getRoutes.d.ts.map +1 -1
  38. package/build/getRoutes.js +150 -67
  39. package/build/getRoutes.js.map +1 -1
  40. package/build/getServerManifest.d.ts +14 -33
  41. package/build/getServerManifest.d.ts.map +1 -1
  42. package/build/getServerManifest.js +6 -5
  43. package/build/getServerManifest.js.map +1 -1
  44. package/build/global-state/router-store.d.ts.map +1 -1
  45. package/build/global-state/router-store.js +29 -3
  46. package/build/global-state/router-store.js.map +1 -1
  47. package/build/global-state/routing.d.ts +0 -4
  48. package/build/global-state/routing.d.ts.map +1 -1
  49. package/build/global-state/routing.js +76 -96
  50. package/build/global-state/routing.js.map +1 -1
  51. package/build/head/ExpoHead.ios.js +4 -4
  52. package/build/head/ExpoHead.ios.js.map +1 -1
  53. package/build/head/ExpoHead.js +1 -1
  54. package/build/head/ExpoHead.js.map +1 -1
  55. package/build/head/url.d.ts.map +1 -1
  56. package/build/head/url.js +5 -6
  57. package/build/head/url.js.map +1 -1
  58. package/build/hooks.d.ts.map +1 -1
  59. package/build/hooks.js +24 -5
  60. package/build/hooks.js.map +1 -1
  61. package/build/import-mode/index.d.ts +1 -1
  62. package/build/import-mode/index.d.ts.map +1 -1
  63. package/build/import-mode/index.js +1 -1
  64. package/build/import-mode/index.js.map +1 -1
  65. package/build/layouts/Tabs.js +2 -2
  66. package/build/layouts/Tabs.js.map +1 -1
  67. package/build/layouts/withLayoutContext.js +1 -1
  68. package/build/layouts/withLayoutContext.js.map +1 -1
  69. package/build/link/Link.d.ts +54 -1
  70. package/build/link/Link.d.ts.map +1 -1
  71. package/build/link/Link.js +54 -12
  72. package/build/link/Link.js.map +1 -1
  73. package/build/link/useLinkToPathProps.js +2 -2
  74. package/build/link/useLinkToPathProps.js.map +1 -1
  75. package/build/loadStaticParamsAsync.d.ts +1 -0
  76. package/build/loadStaticParamsAsync.d.ts.map +1 -1
  77. package/build/loadStaticParamsAsync.js +107 -72
  78. package/build/loadStaticParamsAsync.js.map +1 -1
  79. package/build/matchers.js +1 -1
  80. package/build/matchers.js.map +1 -1
  81. package/build/onboard/Tutorial.js +41 -34
  82. package/build/onboard/Tutorial.js.map +1 -1
  83. package/build/qualified-entry.d.ts.map +1 -1
  84. package/build/qualified-entry.js +10 -7
  85. package/build/qualified-entry.js.map +1 -1
  86. package/build/renderRootComponent.d.ts.map +1 -1
  87. package/build/renderRootComponent.js +28 -4
  88. package/build/renderRootComponent.js.map +1 -1
  89. package/build/routes-manifest.d.ts +1 -0
  90. package/build/routes-manifest.d.ts.map +1 -1
  91. package/build/routes-manifest.js +1 -0
  92. package/build/routes-manifest.js.map +1 -1
  93. package/build/sortRoutes.d.ts.map +1 -1
  94. package/build/sortRoutes.js +21 -2
  95. package/build/sortRoutes.js.map +1 -1
  96. package/build/static/html.d.ts.map +1 -1
  97. package/build/static/html.js +12 -10
  98. package/build/static/html.js.map +1 -1
  99. package/build/static/renderStaticContent.d.ts +13 -3
  100. package/build/static/renderStaticContent.d.ts.map +1 -1
  101. package/build/static/renderStaticContent.js +35 -11
  102. package/build/static/renderStaticContent.js.map +1 -1
  103. package/build/testing-library/index.js +3 -5
  104. package/build/testing-library/index.js.map +1 -1
  105. package/build/testing-library/mocks.d.ts +1 -3
  106. package/build/testing-library/mocks.d.ts.map +1 -1
  107. package/build/testing-library/mocks.js +17 -10
  108. package/build/testing-library/mocks.js.map +1 -1
  109. package/build/testing-library/require-context-ponyfill.js +3 -3
  110. package/build/testing-library/require-context-ponyfill.js.map +1 -1
  111. package/build/useScreens.d.ts.map +1 -1
  112. package/build/useScreens.js +19 -23
  113. package/build/useScreens.js.map +1 -1
  114. package/build/utils/url.d.ts +2 -0
  115. package/build/utils/url.d.ts.map +1 -1
  116. package/build/utils/url.js +13 -1
  117. package/build/utils/url.js.map +1 -1
  118. package/build/views/EmptyRoute.js +5 -2
  119. package/build/views/EmptyRoute.js.map +1 -1
  120. package/build/views/ErrorBoundary.js +50 -31
  121. package/build/views/ErrorBoundary.js.map +1 -1
  122. package/build/views/Navigator.js +16 -10
  123. package/build/views/Navigator.js.map +1 -1
  124. package/build/views/Sitemap.js +54 -36
  125. package/build/views/Sitemap.js.map +1 -1
  126. package/build/views/Splash.d.ts +1 -27
  127. package/build/views/Splash.d.ts.map +1 -1
  128. package/build/views/Splash.js +2 -112
  129. package/build/views/Splash.js.map +1 -1
  130. package/build/views/SuspenseFallback.d.ts +1 -1
  131. package/build/views/SuspenseFallback.d.ts.map +1 -1
  132. package/build/views/SuspenseFallback.js +7 -2
  133. package/build/views/SuspenseFallback.js.map +1 -1
  134. package/build/views/Toast.js +23 -18
  135. package/build/views/Toast.js.map +1 -1
  136. package/build/views/Try.js +1 -1
  137. package/build/views/Try.js.map +1 -1
  138. package/build/views/Unmatched.js +29 -17
  139. package/build/views/Unmatched.js.map +1 -1
  140. package/html.d.ts +1 -0
  141. package/ios/ExpoHead.podspec +1 -1
  142. package/ios/ExpoHeadModule.swift +0 -2
  143. package/package.json +11 -19
  144. package/plugin/build/index.d.ts +2 -2
  145. package/plugin/options.json +3 -3
  146. package/build/fork/react-native-web-container.d.ts +0 -8
  147. package/build/fork/react-native-web-container.d.ts.map +0 -1
  148. package/build/fork/react-native-web-container.js +0 -8
  149. package/build/fork/react-native-web-container.js.map +0 -1
  150. package/build/import-mode/index.android.d.ts +0 -3
  151. package/build/import-mode/index.android.d.ts.map +0 -1
  152. package/build/import-mode/index.android.js +0 -4
  153. package/build/import-mode/index.android.js.map +0 -1
  154. package/build/import-mode/index.ios.d.ts +0 -3
  155. package/build/import-mode/index.ios.d.ts.map +0 -1
  156. package/build/import-mode/index.ios.js +0 -4
  157. package/build/import-mode/index.ios.js.map +0 -1
  158. package/build/import-mode/index.web.d.ts +0 -3
  159. package/build/import-mode/index.web.d.ts.map +0 -1
  160. package/build/import-mode/index.web.js +0 -4
  161. package/build/import-mode/index.web.js.map +0 -1
  162. package/build/link/stateOperations.d.ts +0 -81
  163. package/build/link/stateOperations.d.ts.map +0 -1
  164. package/build/link/stateOperations.js +0 -105
  165. package/build/link/stateOperations.js.map +0 -1
  166. package/types/global.d.ts +0 -38
  167. package/types/metro-require.d.ts +0 -52
  168. package/types/react-native-web.d.ts +0 -295
@@ -1 +1 @@
1
- {"version":3,"file":"getServerManifest.js","sourceRoot":"","sources":["../src/getServerManifest.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Copyright © 2023 650 Industries.\n * Copyright © 2023 Vercel, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n * Based on https://github.com/vercel/next.js/blob/1df2686bc9964f1a86c444701fa5cbf178669833/packages/next/src/shared/lib/router/utils/route-regex.ts\n */\nimport type { RouteNode } from './Route';\nimport { getContextKey } from './matchers';\nimport { sortRoutes } from './sortRoutes';\n\nexport interface Group {\n pos: number;\n repeat: boolean;\n optional: boolean;\n}\n\nexport interface RouteRegex {\n groups: { [groupName: string]: Group };\n re: RegExp;\n}\n\nfunction isApiRoute(route: RouteNode) {\n return !route.children.length && !!route.contextKey.match(/\\+api\\.[jt]sx?$/);\n}\n\nfunction isNotFoundRoute(route: RouteNode) {\n if (route.route === '404') {\n return true;\n }\n return route.dynamic?.length && route.dynamic[0].name === '404';\n}\n\n// Given a nested route tree, return a flattened array of all routes that can be matched.\nexport function getServerManifest(route: RouteNode) {\n function getFlatNodes(route: RouteNode): [string, RouteNode][] {\n if (route.children.length) {\n return route.children.map((child) => getFlatNodes(child)).flat();\n }\n\n const key = getContextKey(route.contextKey).replace(/\\/index$/, '') ?? '/';\n return [[key, route]];\n }\n\n const flat = getFlatNodes(route)\n .sort(([, a], [, b]) => sortRoutes(b, a))\n .reverse();\n\n const apiRoutes = flat.filter(([, route]) => isApiRoute(route));\n const otherRoutes = flat.filter(([, route]) => !isApiRoute(route));\n const standardRoutes = otherRoutes.filter(([, route]) => !isNotFoundRoute(route));\n const notFoundRoutes = otherRoutes.filter(([, route]) => isNotFoundRoute(route));\n\n return {\n apiRoutes: getMatchableManifestForPaths(\n apiRoutes.map(([normalizedRoutePath, node]) => [normalizedRoutePath, node])\n ),\n htmlRoutes: getMatchableManifestForPaths(\n standardRoutes.map(([normalizedRoutePath, node]) => [normalizedRoutePath, node])\n ),\n notFoundRoutes: getMatchableManifestForPaths(\n notFoundRoutes.map(([normalizedRoutePath, node]) => [normalizedRoutePath, node])\n ),\n };\n}\n\nfunction getMatchableManifestForPaths(paths: [string, RouteNode][]) {\n return paths.map((normalizedRoutePath) => ({\n ...getNamedRouteRegex(normalizedRoutePath[0], normalizedRoutePath[1].contextKey),\n generated: normalizedRoutePath[1].generated,\n }));\n}\n\nexport function getNamedRouteRegex(normalizedRoute: string, page: string) {\n const result = getNamedParametrizedRoute(normalizedRoute);\n return {\n page: page.replace(/\\.[jt]sx?$/, ''),\n namedRegex: `^${result.namedParameterizedRoute}(?:/)?$`,\n routeKeys: result.routeKeys,\n };\n}\n\n/**\n * Builds a function to generate a minimal routeKey using only a-z and minimal\n * number of characters.\n */\nfunction buildGetSafeRouteKey() {\n let currentCharCode = 96; // Starting one before 'a' to make the increment logic simpler\n let currentLength = 1;\n\n return () => {\n let result = '';\n let incrementNext = true;\n\n // Iterate from right to left to build the key\n for (let i = 0; i < currentLength; i++) {\n if (incrementNext) {\n currentCharCode++;\n if (currentCharCode > 122) {\n currentCharCode = 97; // Reset to 'a'\n incrementNext = true; // Continue to increment the next character\n } else {\n incrementNext = false;\n }\n }\n result = String.fromCharCode(currentCharCode) + result;\n }\n\n // If all characters are 'z', increase the length of the key\n if (incrementNext) {\n currentLength++;\n currentCharCode = 96; // This will make the next key start with 'a'\n }\n\n return result;\n };\n}\n\nfunction removeTrailingSlash(route: string) {\n return route.replace(/\\/$/, '') || '/';\n}\n\nfunction getNamedParametrizedRoute(route: string) {\n const segments = removeTrailingSlash(route).slice(1).split('/');\n const getSafeRouteKey = buildGetSafeRouteKey();\n const routeKeys: { [named: string]: string } = {};\n return {\n namedParameterizedRoute: segments\n .map((segment) => {\n if (/^\\[.*\\]$/.test(segment)) {\n const { name, optional, repeat } = parseParameter(segment.slice(1, -1));\n // replace any non-word characters since they can break\n // the named regex\n let cleanedKey = name.replace(/\\W/g, '');\n let invalidKey = false;\n\n // check if the key is still invalid and fallback to using a known\n // safe key\n if (cleanedKey.length === 0 || cleanedKey.length > 30) {\n invalidKey = true;\n }\n if (!isNaN(parseInt(cleanedKey.slice(0, 1), 10))) {\n invalidKey = true;\n }\n\n // Prevent duplicates after sanitizing the key\n if (cleanedKey in routeKeys) {\n invalidKey = true;\n }\n\n if (invalidKey) {\n cleanedKey = getSafeRouteKey();\n }\n\n routeKeys[cleanedKey] = name;\n return repeat\n ? optional\n ? `(?:/(?<${cleanedKey}>.+?))?`\n : `/(?<${cleanedKey}>.+?)`\n : `/(?<${cleanedKey}>[^/]+?)`;\n } else if (/^\\(.*\\)$/.test(segment)) {\n // Make section optional\n return `(?:/${escapeStringRegexp(segment)})?`;\n } else {\n return `/${escapeStringRegexp(segment)}`;\n }\n })\n .join(''),\n routeKeys,\n };\n}\n\n// regexp is based on https://github.com/sindresorhus/escape-string-regexp\nconst reHasRegExp = /[|\\\\{}()[\\]^$+*?.-]/;\nconst reReplaceRegExp = /[|\\\\{}()[\\]^$+*?.-]/g;\n\nfunction escapeStringRegexp(str: string) {\n // see also: https://github.com/lodash/lodash/blob/2da024c3b4f9947a48517639de7560457cd4ec6c/escapeRegExp.js#L23\n if (reHasRegExp.test(str)) {\n return str.replace(reReplaceRegExp, '\\\\$&');\n }\n return str;\n}\n\nfunction parseParameter(param: string) {\n let repeat = false;\n let optional = false;\n let name = param;\n\n if (/^\\[.*\\]$/.test(name)) {\n optional = true;\n name = name.slice(1, -1);\n }\n\n if (/^\\.\\.\\./.test(name)) {\n repeat = true;\n name = name.slice(3);\n }\n\n return { name, repeat, optional };\n}\n"]}
1
+ {"version":3,"file":"getServerManifest.js","sourceRoot":"","sources":["../src/getServerManifest.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Copyright © 2023 650 Industries.\n * Copyright © 2023 Vercel, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n * Based on https://github.com/vercel/next.js/blob/1df2686bc9964f1a86c444701fa5cbf178669833/packages/next/src/shared/lib/router/utils/route-regex.ts\n */\nimport type { RouteNode } from './Route';\nimport { getContextKey } from './matchers';\nimport { sortRoutes } from './sortRoutes';\n\n// TODO: Share these types across cli, server, router, etc.\nexport type ExpoRouterServerManifestV1Route<TRegex = string> = {\n file: string;\n page: string;\n routeKeys: Record<string, string>;\n namedRegex: TRegex;\n generated?: boolean;\n};\n\nexport type ExpoRouterServerManifestV1<TRegex = string> = {\n apiRoutes: ExpoRouterServerManifestV1Route<TRegex>[];\n htmlRoutes: ExpoRouterServerManifestV1Route<TRegex>[];\n notFoundRoutes: ExpoRouterServerManifestV1Route<TRegex>[];\n};\n\nexport interface Group {\n pos: number;\n repeat: boolean;\n optional: boolean;\n}\n\nexport interface RouteRegex {\n groups: { [groupName: string]: Group };\n re: RegExp;\n}\n\nfunction isApiRoute(route: RouteNode) {\n return !route.children.length && !!route.contextKey.match(/\\+api\\.[jt]sx?$/);\n}\n\nfunction isNotFoundRoute(route: RouteNode) {\n return route.dynamic && route.dynamic[route.dynamic.length - 1].notFound;\n}\n\n// Given a nested route tree, return a flattened array of all routes that can be matched.\nexport function getServerManifest(route: RouteNode): ExpoRouterServerManifestV1 {\n function getFlatNodes(route: RouteNode): [string, RouteNode][] {\n if (route.children.length) {\n return route.children.map((child) => getFlatNodes(child)).flat();\n }\n\n const key = getContextKey(route.contextKey).replace(/\\/index$/, '') ?? '/';\n return [[key, route]];\n }\n\n const flat = getFlatNodes(route)\n .sort(([, a], [, b]) => sortRoutes(b, a))\n .reverse();\n\n const apiRoutes = flat.filter(([, route]) => isApiRoute(route));\n const otherRoutes = flat.filter(([, route]) => !isApiRoute(route));\n const standardRoutes = otherRoutes.filter(([, route]) => !isNotFoundRoute(route));\n const notFoundRoutes = otherRoutes.filter(([, route]) => isNotFoundRoute(route));\n\n return {\n apiRoutes: getMatchableManifestForPaths(\n apiRoutes.map(([normalizedRoutePath, node]) => [normalizedRoutePath, node])\n ),\n htmlRoutes: getMatchableManifestForPaths(\n standardRoutes.map(([normalizedRoutePath, node]) => [normalizedRoutePath, node])\n ),\n notFoundRoutes: getMatchableManifestForPaths(\n notFoundRoutes.map(([normalizedRoutePath, node]) => [normalizedRoutePath, node])\n ),\n };\n}\n\nfunction getMatchableManifestForPaths(\n paths: [string, RouteNode][]\n): ExpoRouterServerManifestV1Route[] {\n return paths.map((normalizedRoutePath) => ({\n ...getNamedRouteRegex(normalizedRoutePath[0], normalizedRoutePath[1].contextKey),\n generated: normalizedRoutePath[1].generated,\n }));\n}\n\nexport function getNamedRouteRegex(\n normalizedRoute: string,\n page: string\n): ExpoRouterServerManifestV1Route {\n const result = getNamedParametrizedRoute(normalizedRoute);\n return {\n file: page,\n page: page.replace(/\\.[jt]sx?$/, ''),\n namedRegex: `^${result.namedParameterizedRoute}(?:/)?$`,\n routeKeys: result.routeKeys,\n };\n}\n\n/**\n * Builds a function to generate a minimal routeKey using only a-z and minimal\n * number of characters.\n */\nfunction buildGetSafeRouteKey() {\n let currentCharCode = 96; // Starting one before 'a' to make the increment logic simpler\n let currentLength = 1;\n\n return () => {\n let result = '';\n let incrementNext = true;\n\n // Iterate from right to left to build the key\n for (let i = 0; i < currentLength; i++) {\n if (incrementNext) {\n currentCharCode++;\n if (currentCharCode > 122) {\n currentCharCode = 97; // Reset to 'a'\n incrementNext = true; // Continue to increment the next character\n } else {\n incrementNext = false;\n }\n }\n result = String.fromCharCode(currentCharCode) + result;\n }\n\n // If all characters are 'z', increase the length of the key\n if (incrementNext) {\n currentLength++;\n currentCharCode = 96; // This will make the next key start with 'a'\n }\n\n return result;\n };\n}\n\nfunction removeTrailingSlash(route: string): string {\n return route.replace(/\\/$/, '') || '/';\n}\n\nfunction getNamedParametrizedRoute(route: string) {\n const segments = removeTrailingSlash(route).slice(1).split('/');\n const getSafeRouteKey = buildGetSafeRouteKey();\n const routeKeys: { [named: string]: string } = {};\n return {\n namedParameterizedRoute: segments\n .map((segment, index) => {\n if (segment === '+not-found' && index === segments.length - 1) {\n segment = '[...not-found]';\n }\n if (/^\\[.*\\]$/.test(segment)) {\n const { name, optional, repeat } = parseParameter(segment.slice(1, -1));\n // replace any non-word characters since they can break\n // the named regex\n let cleanedKey = name.replace(/\\W/g, '');\n let invalidKey = false;\n\n // check if the key is still invalid and fallback to using a known\n // safe key\n if (cleanedKey.length === 0 || cleanedKey.length > 30) {\n invalidKey = true;\n }\n if (!isNaN(parseInt(cleanedKey.slice(0, 1), 10))) {\n invalidKey = true;\n }\n\n // Prevent duplicates after sanitizing the key\n if (cleanedKey in routeKeys) {\n invalidKey = true;\n }\n\n if (invalidKey) {\n cleanedKey = getSafeRouteKey();\n }\n\n routeKeys[cleanedKey] = name;\n return repeat\n ? optional\n ? `(?:/(?<${cleanedKey}>.+?))?`\n : `/(?<${cleanedKey}>.+?)`\n : `/(?<${cleanedKey}>[^/]+?)`;\n } else if (/^\\(.*\\)$/.test(segment)) {\n // Make section optional\n return `(?:/${escapeStringRegexp(segment)})?`;\n } else {\n return `/${escapeStringRegexp(segment)}`;\n }\n })\n .join(''),\n routeKeys,\n };\n}\n\n// regexp is based on https://github.com/sindresorhus/escape-string-regexp\nconst reHasRegExp = /[|\\\\{}()[\\]^$+*?.-]/;\nconst reReplaceRegExp = /[|\\\\{}()[\\]^$+*?.-]/g;\n\nfunction escapeStringRegexp(str: string) {\n // see also: https://github.com/lodash/lodash/blob/2da024c3b4f9947a48517639de7560457cd4ec6c/escapeRegExp.js#L23\n if (reHasRegExp.test(str)) {\n return str.replace(reReplaceRegExp, '\\\\$&');\n }\n return str;\n}\n\nfunction parseParameter(param: string) {\n let repeat = false;\n let optional = false;\n let name = param;\n\n if (/^\\[.*\\]$/.test(name)) {\n optional = true;\n name = name.slice(1, -1);\n }\n\n if (/^\\.\\.\\./.test(name)) {\n repeat = true;\n name = name.slice(3);\n }\n\n return { name, repeat, optional };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"router-store.d.ts","sourceRoot":"","sources":["../../src/global-state/router-store.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,iCAAiC,EAGlC,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAiC,aAAa,EAAY,MAAM,OAAO,CAAC;AAI/E,OAAO,EAAE,SAAS,EAAyB,MAAM,qBAAqB,CAAC;AACvE,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAErC,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAoB,MAAM,qBAAqB,CAAC;AAE3E,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAI1C;;;;GAIG;AACH,qBAAa,WAAW;IACtB,SAAS,EAAG,SAAS,GAAG,IAAI,CAAC;IAC7B,aAAa,EAAG,aAAa,CAAC;IAC9B,OAAO,EAAE,kBAAkB,GAAG,SAAS,CAAC;IACxC,OAAO,CAAC,wBAAwB,CAAkB;IAElD,YAAY,EAAE,WAAW,GAAG,SAAS,CAAC;IACtC,SAAS,EAAE,WAAW,GAAG,SAAS,CAAC;IACnC,SAAS,EAAE,WAAW,GAAG,SAAS,CAAC;IACnC,SAAS,CAAC,EAAE,SAAS,GAAG,SAAS,CAAC;IAElC,aAAa,EAAG,iCAAiC,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC;IACjF,yBAAyB,EAAG,MAAM,IAAI,CAAC;IAEvC,oBAAoB,YAAiB,IAAI,EAAI;IAC7C,gBAAgB,YAAiB,IAAI,EAAI;IAEzC,MAAM,MAAqB;IAC3B,eAAe,MAA8B;IAC7C,MAAM,MAAqB;IAC3B,SAAS,MAAwB;IACjC,IAAI,MAAmB;IACvB,OAAO,MAAsB;IAC7B,SAAS,MAAwB;IAEjC,UAAU,CACR,OAAO,EAAE,cAAc,EACvB,aAAa,EAAE,iCAAiC,CAAC,eAAe,CAAC,aAAa,CAAC,EAC/E,eAAe,CAAC,EAAE,GAAG;IA4FvB,WAAW,CAAC,KAAK,EAAE,WAAW,EAAE,SAAS,cAAQ;IAWjD,YAAY,CAAC,KAAK,EAAE,WAAW;IAgB/B,kBAAkB;IAIlB,uEAAuE;IACvE,oBAAoB,eAAgB,MAAM,IAAI,mBAG5C;IACF,gBAAgB,eAAgB,MAAM,IAAI,mBAGxC;IACF,QAAQ,aAEN;IACF,iBAAiB,oBAEf;IACF,iBAAiB,kBAEf;CACH;AAED,eAAO,MAAM,KAAK,aAAoB,CAAC;AAEvC,wBAAgB,aAAa,gBAE5B;AAYD,wBAAgB,iBAAiB,gBAOhC;AAED,wBAAgB,iBAAiB,cAOhC;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,GAAG,GAAG,SAAS,eAQhG"}
1
+ {"version":3,"file":"router-store.d.ts","sourceRoot":"","sources":["../../src/global-state/router-store.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,iCAAiC,EAGlC,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAiC,aAAa,EAAY,MAAM,OAAO,CAAC;AAI/E,OAAO,EAAE,SAAS,EAAyB,MAAM,qBAAqB,CAAC;AACvE,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAErC,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAoB,MAAM,qBAAqB,CAAC;AAE3E,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAG1C;;;;GAIG;AACH,qBAAa,WAAW;IACtB,SAAS,EAAG,SAAS,GAAG,IAAI,CAAC;IAC7B,aAAa,EAAG,aAAa,CAAC;IAC9B,OAAO,EAAE,kBAAkB,GAAG,SAAS,CAAC;IACxC,OAAO,CAAC,wBAAwB,CAAkB;IAElD,YAAY,EAAE,WAAW,GAAG,SAAS,CAAC;IACtC,SAAS,EAAE,WAAW,GAAG,SAAS,CAAC;IACnC,SAAS,EAAE,WAAW,GAAG,SAAS,CAAC;IACnC,SAAS,CAAC,EAAE,SAAS,GAAG,SAAS,CAAC;IAElC,aAAa,EAAG,iCAAiC,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC;IACjF,yBAAyB,EAAG,MAAM,IAAI,CAAC;IAEvC,oBAAoB,YAAiB,IAAI,EAAI;IAC7C,gBAAgB,YAAiB,IAAI,EAAI;IAEzC,MAAM,MAAqB;IAC3B,eAAe,MAA8B;IAC7C,MAAM,MAAqB;IAC3B,SAAS,MAAwB;IACjC,IAAI,MAAmB;IACvB,OAAO,MAAsB;IAC7B,SAAS,MAAwB;IAEjC,UAAU,CACR,OAAO,EAAE,cAAc,EACvB,aAAa,EAAE,iCAAiC,CAAC,eAAe,CAAC,aAAa,CAAC,EAC/E,eAAe,CAAC,EAAE,GAAG;IAiGvB,WAAW,CAAC,KAAK,EAAE,WAAW,EAAE,SAAS,cAAQ;IAWjD,YAAY,CAAC,KAAK,EAAE,WAAW;IAgB/B,kBAAkB;IAIlB,uEAAuE;IACvE,oBAAoB,eAAgB,MAAM,IAAI,mBAG5C;IACF,gBAAgB,eAAgB,MAAM,IAAI,mBAGxC;IACF,QAAQ,aAEN;IACF,iBAAiB,oBAEf;IACF,iBAAiB,kBAEf;CACH;AAED,eAAO,MAAM,KAAK,aAAoB,CAAC;AAEvC,wBAAgB,aAAa,gBAE5B;AAYD,wBAAgB,iBAAiB,gBAOhC;AAED,wBAAgB,iBAAiB,cAOhC;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,GAAG,GAAG,SAAS,eAQhG"}
@@ -1,7 +1,31 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
2
25
  Object.defineProperty(exports, "__esModule", { value: true });
3
26
  exports.useInitializeExpoRouter = exports.useStoreRouteInfo = exports.useStoreRootState = exports.useExpoRouter = exports.store = exports.RouterStore = void 0;
4
27
  const native_1 = require("@react-navigation/native");
28
+ const SplashScreen = __importStar(require("expo-splash-screen"));
5
29
  const react_1 = require("react");
6
30
  const routing_1 = require("./routing");
7
31
  const sort_routes_1 = require("./sort-routes");
@@ -10,7 +34,6 @@ const getPathFromState_1 = require("../fork/getPathFromState");
10
34
  const getLinkingConfig_1 = require("../getLinkingConfig");
11
35
  const getRoutes_1 = require("../getRoutes");
12
36
  const useScreens_1 = require("../useScreens");
13
- const Splash_1 = require("../views/Splash");
14
37
  /**
15
38
  * This is the global state for the router. It is used to keep track of the current route, and to provide a way to navigate to other routes.
16
39
  *
@@ -46,7 +69,7 @@ class RouterStore {
46
69
  this.navigationRefSubscription?.();
47
70
  this.rootStateSubscribers.clear();
48
71
  this.storeSubscribers.clear();
49
- this.routeNode = (0, getRoutes_1.getRoutes)(context);
72
+ this.routeNode = (0, getRoutes_1.getRoutes)(context, { ignoreEntryPoints: true });
50
73
  this.rootComponent = this.routeNode ? (0, useScreens_1.getQualifiedRouteComponent)(this.routeNode) : react_1.Fragment;
51
74
  // Only error in production, in development we will show the onboarding screen
52
75
  if (!this.routeNode && process.env.NODE_ENV === 'production') {
@@ -70,6 +93,7 @@ class RouterStore {
70
93
  this.routeInfo = {
71
94
  unstable_globalHref: '',
72
95
  pathname: '',
96
+ isIndex: false,
73
97
  params: {},
74
98
  segments: [],
75
99
  };
@@ -90,7 +114,9 @@ class RouterStore {
90
114
  if (!this.hasAttemptedToHideSplash) {
91
115
  this.hasAttemptedToHideSplash = true;
92
116
  // NOTE(EvanBacon): `navigationRef.isReady` is sometimes not true when state is called initially.
93
- requestAnimationFrame(() => (0, Splash_1._internal_maybeHideAsync)());
117
+ requestAnimationFrame(() =>
118
+ // @ts-expect-error: This function is native-only and for internal-use only.
119
+ SplashScreen._internal_maybeHideAsync?.());
94
120
  }
95
121
  let shouldUpdateSubscribers = this.nextState === state;
96
122
  this.nextState = undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"router-store.js","sourceRoot":"","sources":["../../src/global-state/router-store.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n NavigationContainerRefWithCurrent,\n getPathFromState,\n useNavigationContainerRef,\n} from '@react-navigation/native';\nimport { useSyncExternalStore, useMemo, ComponentType, Fragment } from 'react';\n\nimport { canGoBack, goBack, linkTo, push, replace, setParams } from './routing';\nimport { getSortedRoutes } from './sort-routes';\nimport { UrlObject, getRouteInfoFromState } from '../LocationProvider';\nimport { RouteNode } from '../Route';\nimport { deepEqual, getPathDataFromState } from '../fork/getPathFromState';\nimport { ResultState } from '../fork/getStateFromPath';\nimport { ExpoLinkingOptions, getLinkingConfig } from '../getLinkingConfig';\nimport { getRoutes } from '../getRoutes';\nimport { RequireContext } from '../types';\nimport { getQualifiedRouteComponent } from '../useScreens';\nimport { _internal_maybeHideAsync } from '../views/Splash';\n\n/**\n * This is the global state for the router. It is used to keep track of the current route, and to provide a way to navigate to other routes.\n *\n * There should only be one instance of this class and be initialized via `useInitializeExpoRouter`\n */\nexport class RouterStore {\n routeNode!: RouteNode | null;\n rootComponent!: ComponentType;\n linking: ExpoLinkingOptions | undefined;\n private hasAttemptedToHideSplash: boolean = false;\n\n initialState: ResultState | undefined;\n rootState: ResultState | undefined;\n nextState: ResultState | undefined;\n routeInfo?: UrlObject | undefined;\n\n navigationRef!: NavigationContainerRefWithCurrent<ReactNavigation.RootParamList>;\n navigationRefSubscription!: () => void;\n\n rootStateSubscribers = new Set<() => void>();\n storeSubscribers = new Set<() => void>();\n\n linkTo = linkTo.bind(this);\n getSortedRoutes = getSortedRoutes.bind(this);\n goBack = goBack.bind(this);\n canGoBack = canGoBack.bind(this);\n push = push.bind(this);\n replace = replace.bind(this);\n setParams = setParams.bind(this);\n\n initialize(\n context: RequireContext,\n navigationRef: NavigationContainerRefWithCurrent<ReactNavigation.RootParamList>,\n initialLocation?: URL\n ) {\n // Clean up any previous state\n this.initialState = undefined;\n this.rootState = undefined;\n this.nextState = undefined;\n this.routeInfo = undefined;\n this.linking = undefined;\n this.navigationRefSubscription?.();\n this.rootStateSubscribers.clear();\n this.storeSubscribers.clear();\n\n this.routeNode = getRoutes(context);\n\n this.rootComponent = this.routeNode ? getQualifiedRouteComponent(this.routeNode) : Fragment;\n\n // Only error in production, in development we will show the onboarding screen\n if (!this.routeNode && process.env.NODE_ENV === 'production') {\n throw new Error('No routes found');\n }\n\n this.navigationRef = navigationRef;\n\n if (this.routeNode) {\n this.linking = getLinkingConfig(this.routeNode!);\n\n if (initialLocation) {\n this.linking.getInitialURL = () => initialLocation.toString();\n this.initialState = this.linking.getStateFromPath?.(\n initialLocation.pathname + initialLocation.search,\n this.linking.config\n );\n }\n }\n\n // There is no routeNode, so we will be showing the onboarding screen\n // In the meantime, just mock the routeInfo\n if (this.initialState) {\n this.rootState = this.initialState;\n this.routeInfo = this.getRouteInfo(this.initialState);\n } else {\n this.routeInfo = {\n unstable_globalHref: '',\n pathname: '',\n params: {},\n segments: [],\n };\n }\n\n /**\n * Counter intuitively - this fires AFTER both React Navigations state change and the subsequent paint.\n * This poses a couple of issues for Expo Router,\n * - Ensuring hooks (e.g. useSearchParams()) have data in the initial render\n * - Reacting to state changes after a navigation event\n *\n * This is why the initial render renders a Fragment and we wait until `onReady()` is called\n * Additionally, some hooks compare the state from both the store and the navigationRef. If the store it stale,\n * that hooks will manually update the store.\n *\n */\n this.navigationRefSubscription = navigationRef.addListener('state', (data) => {\n const state = data.data.state as ResultState;\n\n if (!this.hasAttemptedToHideSplash) {\n this.hasAttemptedToHideSplash = true;\n // NOTE(EvanBacon): `navigationRef.isReady` is sometimes not true when state is called initially.\n requestAnimationFrame(() => _internal_maybeHideAsync());\n }\n\n let shouldUpdateSubscribers = this.nextState === state;\n this.nextState = undefined;\n\n // This can sometimes be undefined when an error is thrown in the Root Layout Route.\n // Additionally that state may already equal the rootState if it was updated within a hook\n if (state && state !== this.rootState) {\n store.updateState(state, undefined);\n shouldUpdateSubscribers = true;\n }\n\n // If the state has changed, or was changed inside a hook we need to update the subscribers\n if (shouldUpdateSubscribers) {\n for (const subscriber of this.rootStateSubscribers) {\n subscriber();\n }\n }\n });\n\n for (const subscriber of this.storeSubscribers) {\n subscriber();\n }\n }\n\n updateState(state: ResultState, nextState = state) {\n store.rootState = state;\n store.nextState = nextState;\n\n const nextRouteInfo = store.getRouteInfo(state);\n\n if (!deepEqual(this.routeInfo, nextRouteInfo)) {\n store.routeInfo = nextRouteInfo;\n }\n }\n\n getRouteInfo(state: ResultState) {\n return getRouteInfoFromState(\n (state: Parameters<typeof getPathFromState>[0], asPath: boolean) => {\n return getPathDataFromState(state, {\n screens: [],\n ...this.linking?.config,\n preserveDynamicRoutes: asPath,\n preserveGroups: asPath,\n });\n },\n state\n );\n }\n\n // This is only used in development, to show the onboarding screen\n // In production we should have errored during the initialization\n shouldShowTutorial() {\n return !this.routeNode && process.env.NODE_ENV === 'development';\n }\n\n /** Make sure these are arrow functions so `this` is correctly bound */\n subscribeToRootState = (subscriber: () => void) => {\n this.rootStateSubscribers.add(subscriber);\n return () => this.rootStateSubscribers.delete(subscriber);\n };\n subscribeToStore = (subscriber: () => void) => {\n this.storeSubscribers.add(subscriber);\n return () => this.storeSubscribers.delete(subscriber);\n };\n snapshot = () => {\n return this;\n };\n rootStateSnapshot = () => {\n return this.rootState!;\n };\n routeInfoSnapshot = () => {\n return this.routeInfo!;\n };\n}\n\nexport const store = new RouterStore();\n\nexport function useExpoRouter() {\n return useSyncExternalStore(store.subscribeToStore, store.snapshot, store.snapshot);\n}\n\nfunction syncStoreRootState() {\n if (store.navigationRef.isReady()) {\n const currentState = store.navigationRef.getRootState() as unknown as ResultState;\n\n if (store.rootState !== currentState) {\n store.updateState(currentState);\n }\n }\n}\n\nexport function useStoreRootState() {\n syncStoreRootState();\n return useSyncExternalStore(\n store.subscribeToRootState,\n store.rootStateSnapshot,\n store.rootStateSnapshot\n );\n}\n\nexport function useStoreRouteInfo() {\n syncStoreRootState();\n return useSyncExternalStore(\n store.subscribeToRootState,\n store.routeInfoSnapshot,\n store.routeInfoSnapshot\n );\n}\n\nexport function useInitializeExpoRouter(context: RequireContext, initialLocation: URL | undefined) {\n const navigationRef = useNavigationContainerRef();\n useMemo(\n () => store.initialize(context, navigationRef, initialLocation),\n [context, initialLocation]\n );\n useExpoRouter();\n return store;\n}\n"]}
1
+ {"version":3,"file":"router-store.js","sourceRoot":"","sources":["../../src/global-state/router-store.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n NavigationContainerRefWithCurrent,\n getPathFromState,\n useNavigationContainerRef,\n} from '@react-navigation/native';\nimport * as SplashScreen from 'expo-splash-screen';\nimport { useSyncExternalStore, useMemo, ComponentType, Fragment } from 'react';\n\nimport { canGoBack, goBack, linkTo, push, replace, setParams } from './routing';\nimport { getSortedRoutes } from './sort-routes';\nimport { UrlObject, getRouteInfoFromState } from '../LocationProvider';\nimport { RouteNode } from '../Route';\nimport { deepEqual, getPathDataFromState } from '../fork/getPathFromState';\nimport { ResultState } from '../fork/getStateFromPath';\nimport { ExpoLinkingOptions, getLinkingConfig } from '../getLinkingConfig';\nimport { getRoutes } from '../getRoutes';\nimport { RequireContext } from '../types';\nimport { getQualifiedRouteComponent } from '../useScreens';\n\n/**\n * This is the global state for the router. It is used to keep track of the current route, and to provide a way to navigate to other routes.\n *\n * There should only be one instance of this class and be initialized via `useInitializeExpoRouter`\n */\nexport class RouterStore {\n routeNode!: RouteNode | null;\n rootComponent!: ComponentType;\n linking: ExpoLinkingOptions | undefined;\n private hasAttemptedToHideSplash: boolean = false;\n\n initialState: ResultState | undefined;\n rootState: ResultState | undefined;\n nextState: ResultState | undefined;\n routeInfo?: UrlObject | undefined;\n\n navigationRef!: NavigationContainerRefWithCurrent<ReactNavigation.RootParamList>;\n navigationRefSubscription!: () => void;\n\n rootStateSubscribers = new Set<() => void>();\n storeSubscribers = new Set<() => void>();\n\n linkTo = linkTo.bind(this);\n getSortedRoutes = getSortedRoutes.bind(this);\n goBack = goBack.bind(this);\n canGoBack = canGoBack.bind(this);\n push = push.bind(this);\n replace = replace.bind(this);\n setParams = setParams.bind(this);\n\n initialize(\n context: RequireContext,\n navigationRef: NavigationContainerRefWithCurrent<ReactNavigation.RootParamList>,\n initialLocation?: URL\n ) {\n // Clean up any previous state\n this.initialState = undefined;\n this.rootState = undefined;\n this.nextState = undefined;\n this.routeInfo = undefined;\n this.linking = undefined;\n this.navigationRefSubscription?.();\n this.rootStateSubscribers.clear();\n this.storeSubscribers.clear();\n\n this.routeNode = getRoutes(context, { ignoreEntryPoints: true });\n\n this.rootComponent = this.routeNode ? getQualifiedRouteComponent(this.routeNode) : Fragment;\n\n // Only error in production, in development we will show the onboarding screen\n if (!this.routeNode && process.env.NODE_ENV === 'production') {\n throw new Error('No routes found');\n }\n\n this.navigationRef = navigationRef;\n\n if (this.routeNode) {\n this.linking = getLinkingConfig(this.routeNode!);\n\n if (initialLocation) {\n this.linking.getInitialURL = () => initialLocation.toString();\n this.initialState = this.linking.getStateFromPath?.(\n initialLocation.pathname + initialLocation.search,\n this.linking.config\n );\n }\n }\n\n // There is no routeNode, so we will be showing the onboarding screen\n // In the meantime, just mock the routeInfo\n if (this.initialState) {\n this.rootState = this.initialState;\n this.routeInfo = this.getRouteInfo(this.initialState);\n } else {\n this.routeInfo = {\n unstable_globalHref: '',\n pathname: '',\n isIndex: false,\n params: {},\n segments: [],\n };\n }\n\n /**\n * Counter intuitively - this fires AFTER both React Navigations state change and the subsequent paint.\n * This poses a couple of issues for Expo Router,\n * - Ensuring hooks (e.g. useSearchParams()) have data in the initial render\n * - Reacting to state changes after a navigation event\n *\n * This is why the initial render renders a Fragment and we wait until `onReady()` is called\n * Additionally, some hooks compare the state from both the store and the navigationRef. If the store it stale,\n * that hooks will manually update the store.\n *\n */\n this.navigationRefSubscription = navigationRef.addListener('state', (data) => {\n const state = data.data.state as ResultState;\n\n if (!this.hasAttemptedToHideSplash) {\n this.hasAttemptedToHideSplash = true;\n // NOTE(EvanBacon): `navigationRef.isReady` is sometimes not true when state is called initially.\n requestAnimationFrame(\n () =>\n // @ts-expect-error: This function is native-only and for internal-use only.\n SplashScreen._internal_maybeHideAsync?.()\n );\n }\n\n let shouldUpdateSubscribers = this.nextState === state;\n this.nextState = undefined;\n\n // This can sometimes be undefined when an error is thrown in the Root Layout Route.\n // Additionally that state may already equal the rootState if it was updated within a hook\n if (state && state !== this.rootState) {\n store.updateState(state, undefined);\n shouldUpdateSubscribers = true;\n }\n\n // If the state has changed, or was changed inside a hook we need to update the subscribers\n if (shouldUpdateSubscribers) {\n for (const subscriber of this.rootStateSubscribers) {\n subscriber();\n }\n }\n });\n\n for (const subscriber of this.storeSubscribers) {\n subscriber();\n }\n }\n\n updateState(state: ResultState, nextState = state) {\n store.rootState = state;\n store.nextState = nextState;\n\n const nextRouteInfo = store.getRouteInfo(state);\n\n if (!deepEqual(this.routeInfo, nextRouteInfo)) {\n store.routeInfo = nextRouteInfo;\n }\n }\n\n getRouteInfo(state: ResultState) {\n return getRouteInfoFromState(\n (state: Parameters<typeof getPathFromState>[0], asPath: boolean) => {\n return getPathDataFromState(state, {\n screens: [],\n ...this.linking?.config,\n preserveDynamicRoutes: asPath,\n preserveGroups: asPath,\n });\n },\n state\n );\n }\n\n // This is only used in development, to show the onboarding screen\n // In production we should have errored during the initialization\n shouldShowTutorial() {\n return !this.routeNode && process.env.NODE_ENV === 'development';\n }\n\n /** Make sure these are arrow functions so `this` is correctly bound */\n subscribeToRootState = (subscriber: () => void) => {\n this.rootStateSubscribers.add(subscriber);\n return () => this.rootStateSubscribers.delete(subscriber);\n };\n subscribeToStore = (subscriber: () => void) => {\n this.storeSubscribers.add(subscriber);\n return () => this.storeSubscribers.delete(subscriber);\n };\n snapshot = () => {\n return this;\n };\n rootStateSnapshot = () => {\n return this.rootState!;\n };\n routeInfoSnapshot = () => {\n return this.routeInfo!;\n };\n}\n\nexport const store = new RouterStore();\n\nexport function useExpoRouter() {\n return useSyncExternalStore(store.subscribeToStore, store.snapshot, store.snapshot);\n}\n\nfunction syncStoreRootState() {\n if (store.navigationRef.isReady()) {\n const currentState = store.navigationRef.getRootState() as unknown as ResultState;\n\n if (store.rootState !== currentState) {\n store.updateState(currentState);\n }\n }\n}\n\nexport function useStoreRootState() {\n syncStoreRootState();\n return useSyncExternalStore(\n store.subscribeToRootState,\n store.rootStateSnapshot,\n store.rootStateSnapshot\n );\n}\n\nexport function useStoreRouteInfo() {\n syncStoreRootState();\n return useSyncExternalStore(\n store.subscribeToRootState,\n store.routeInfoSnapshot,\n store.routeInfoSnapshot\n );\n}\n\nexport function useInitializeExpoRouter(context: RequireContext, initialLocation: URL | undefined) {\n const navigationRef = useNavigationContainerRef();\n useMemo(\n () => store.initialize(context, navigationRef, initialLocation),\n [context, initialLocation]\n );\n useExpoRouter();\n return store;\n}\n"]}
@@ -1,13 +1,9 @@
1
- import { getActionFromState } from '@react-navigation/core';
2
1
  import type { RouterStore } from './router-store';
3
2
  import { Href } from '../link/href';
4
- import { NavigateAction } from '../link/stateOperations';
5
3
  export declare function push(this: RouterStore, url: Href): any;
6
4
  export declare function replace(this: RouterStore, url: Href): any;
7
5
  export declare function goBack(this: RouterStore): void;
8
6
  export declare function canGoBack(this: RouterStore): boolean;
9
7
  export declare function setParams(this: RouterStore, params?: Record<string, string | number>): any;
10
8
  export declare function linkTo(this: RouterStore, href: string, event?: string): void;
11
- /** @returns `true` if the action is moving to the first screen of all the navigators in the action. */
12
- export declare function isAbsoluteInitialRoute(action: ReturnType<typeof getActionFromState>): action is NavigateAction;
13
9
  //# sourceMappingURL=routing.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"routing.d.ts","sourceRoot":"","sources":["../../src/global-state/routing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,kBAAkB,EAAgB,MAAM,wBAAwB,CAAC;AAIzF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,IAAI,EAAe,MAAM,cAAc,CAAC;AAEjD,OAAO,EACL,cAAc,EAKf,MAAM,yBAAyB,CAAC;AAWjC,wBAAgB,IAAI,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE,IAAI,OAEhD;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE,IAAI,OAEnD;AAED,wBAAgB,MAAM,CAAC,IAAI,EAAE,WAAW,QAGvC;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAUpD;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,WAAW,EAAE,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAM,OAGxF;AAED,wBAAgB,MAAM,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,QA8GrE;AAED,uGAAuG;AACvG,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,UAAU,CAAC,OAAO,kBAAkB,CAAC,GAC5C,MAAM,IAAI,cAAc,CAqB1B"}
1
+ {"version":3,"file":"routing.d.ts","sourceRoot":"","sources":["../../src/global-state/routing.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD,OAAO,EAAE,IAAI,EAAe,MAAM,cAAc,CAAC;AAYjD,wBAAgB,IAAI,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE,IAAI,OAEhD;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE,IAAI,OAEnD;AAED,wBAAgB,MAAM,CAAC,IAAI,EAAE,WAAW,QAGvC;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAUpD;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,WAAW,EAAE,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAM,OAGxF;AAED,wBAAgB,MAAM,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,QAqErE"}
@@ -23,13 +23,10 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.isAbsoluteInitialRoute = exports.linkTo = exports.setParams = exports.canGoBack = exports.goBack = exports.replace = exports.push = void 0;
27
- const core_1 = require("@react-navigation/core");
28
- const native_1 = require("@react-navigation/native");
26
+ exports.linkTo = exports.setParams = exports.canGoBack = exports.goBack = exports.replace = exports.push = void 0;
29
27
  const Linking = __importStar(require("expo-linking"));
30
28
  const href_1 = require("../link/href");
31
29
  const path_1 = require("../link/path");
32
- const stateOperations_1 = require("../link/stateOperations");
33
30
  const url_1 = require("../utils/url");
34
31
  function assertIsReady(store) {
35
32
  if (!store.navigationRef.isReady()) {
@@ -67,7 +64,7 @@ function setParams(params = {}) {
67
64
  }
68
65
  exports.setParams = setParams;
69
66
  function linkTo(href, event) {
70
- if ((0, url_1.hasUrlProtocolPrefix)(href)) {
67
+ if ((0, url_1.shouldLinkExternally)(href)) {
71
68
  Linking.openURL(href);
72
69
  return;
73
70
  }
@@ -83,111 +80,94 @@ function linkTo(href, event) {
83
80
  navigationRef.goBack();
84
81
  return;
85
82
  }
86
- if (href.startsWith('.')) {
87
- let base = this.linking.getPathFromState?.(navigationRef.getRootState(), {
88
- screens: [],
89
- preserveGroups: true,
90
- }) ?? '';
91
- if (base && !base.endsWith('/')) {
92
- base += '/..';
93
- }
94
- href = (0, path_1.resolve)(base, href);
95
- }
96
- const state = this.linking.getStateFromPath(href, this.linking.config);
97
- if (!state) {
98
- console.error('Could not generate a valid navigation state for the given path: ' + href);
99
- return;
100
- }
101
83
  const rootState = navigationRef.getRootState();
102
- // Ensure simple operations are used when moving between siblings
103
- // in the same navigator. This ensures that the state is not reset.
104
- // TODO: We may need to apply this at a larger scale in the future.
105
- if ((0, stateOperations_1.isMovingToSiblingRoute)(rootState, state)) {
106
- // Can perform naive movements
107
- const knownOwnerState = (0, stateOperations_1.getQualifiedStateForTopOfTargetState)(rootState, state);
108
- const nextRoute = (0, stateOperations_1.findTopRouteForTarget)(state);
109
- // NOTE(EvanBacon): There's an issue where moving from "a -> b" is considered siblings:
110
- // a. index (initialRouteName="index")
111
- // b. stack/index
112
- // However, the preservation approach doesn't work because it would be moving to a route with the same name.
113
- // The next check will see if the current focused route has the same name as the next route, if so, then fallback on
114
- // the default React Navigation logic.
115
- if ((0, stateOperations_1.findTopRouteForTarget)(
116
- // @ts-expect-error: stale types don't matter here
117
- rootState)?.name !== nextRoute.name) {
118
- if (event === 'REPLACE') {
119
- if (knownOwnerState.type === 'tab') {
120
- navigationRef.dispatch(native_1.TabActions.jumpTo(nextRoute.name, nextRoute.params));
84
+ if (href.startsWith('.')) {
85
+ // Resolve base path by merging the current segments with the params
86
+ let base = this.routeInfo?.segments
87
+ ?.map((segment) => {
88
+ if (!segment.startsWith('['))
89
+ return segment;
90
+ if (segment.startsWith('[...')) {
91
+ segment = segment.slice(4, -1);
92
+ const params = this.routeInfo?.params?.[segment];
93
+ if (Array.isArray(params)) {
94
+ return params.join('/');
121
95
  }
122
96
  else {
123
- navigationRef.dispatch(core_1.StackActions.replace(nextRoute.name, nextRoute.params));
97
+ return params?.split(',')?.join('/') ?? '';
124
98
  }
125
99
  }
126
100
  else {
127
- // NOTE: Not sure if we should pop or push here...
128
- navigationRef.dispatch(core_1.CommonActions.navigate(nextRoute.name, nextRoute.params));
101
+ segment = segment.slice(1, -1);
102
+ return this.routeInfo?.params?.[segment];
129
103
  }
130
- return;
104
+ })
105
+ .filter(Boolean)
106
+ .join('/') ?? '/';
107
+ if (!this.routeInfo?.isIndex) {
108
+ base += '/..';
131
109
  }
110
+ href = (0, path_1.resolve)(base, href);
132
111
  }
133
- // TODO: Advanced movements across multiple navigators
134
- const action = (0, core_1.getActionFromState)(state, this.linking.config);
135
- if (action) {
136
- // Here we have a navigation action to a nested screen, where we should ideally replace.
137
- // This request can only be fulfilled if the target is an initial route.
138
- // First, check if the action is fully initial routes.
139
- // Then find the nearest mismatched route in the existing state.
140
- // Finally, use the correct navigator-based action to replace the nested screens.
141
- // NOTE(EvanBacon): A future version of this will involve splitting the navigation request so we replace as much as possible, then push the remaining screens to fulfill the request.
142
- if (event === 'REPLACE' && isAbsoluteInitialRoute(action)) {
143
- const earliest = (0, stateOperations_1.getEarliestMismatchedRoute)(rootState, action.payload);
144
- if (earliest) {
145
- if (earliest.type === 'stack') {
146
- navigationRef.dispatch(core_1.StackActions.replace(earliest.name, earliest.params));
147
- }
148
- else {
149
- navigationRef.dispatch(native_1.TabActions.jumpTo(earliest.name, earliest.params));
150
- }
151
- return;
152
- }
153
- else {
154
- // This should never happen because moving to the same route would be handled earlier
155
- // in the sibling operations.
156
- }
157
- }
158
- // Ignore the replace event here since replace across
159
- // navigators is not supported.
160
- navigationRef.dispatch(action);
112
+ const state = this.linking.getStateFromPath(href, this.linking.config);
113
+ if (!state || state.routes.length === 0) {
114
+ console.error('Could not generate a valid navigation state for the given path: ' + href);
115
+ return;
161
116
  }
162
- else {
163
- navigationRef.reset(state);
117
+ switch (event) {
118
+ case 'REPLACE':
119
+ return navigationRef.dispatch(getNavigateReplaceAction(state, rootState));
120
+ default:
121
+ return navigationRef.dispatch(getNavigatePushAction(state, rootState));
164
122
  }
165
123
  }
166
124
  exports.linkTo = linkTo;
167
- /** @returns `true` if the action is moving to the first screen of all the navigators in the action. */
168
- function isAbsoluteInitialRoute(action) {
169
- if (action?.type !== 'NAVIGATE') {
170
- return false;
125
+ function rewriteNavigationStateToParams(state, params = {}) {
126
+ if (!state)
127
+ return params;
128
+ // We Should always have at least one route in the state
129
+ const lastRoute = state.routes[state.routes.length - 1];
130
+ params.screen = lastRoute.name;
131
+ // Weirdly, this always needs to be an object. If it's undefined, it won't work.
132
+ params.params = lastRoute.params ? JSON.parse(JSON.stringify(lastRoute.params)) : {};
133
+ if (lastRoute.state) {
134
+ rewriteNavigationStateToParams(lastRoute.state, params.params);
171
135
  }
172
- let next = action.payload.params;
173
- // iterate all child screens and bail out if any are not initial.
174
- while (next) {
175
- if (!isNavigationState(next)) {
176
- // Not sure when this would happen
177
- return false;
178
- }
179
- if (next.initial === true) {
180
- next = next.params;
181
- // return true;
182
- }
183
- else if (next.initial === false) {
184
- return false;
185
- }
186
- }
187
- return true;
136
+ return JSON.parse(JSON.stringify(params));
188
137
  }
189
- exports.isAbsoluteInitialRoute = isAbsoluteInitialRoute;
190
- function isNavigationState(obj) {
191
- return 'initial' in obj;
138
+ function getNavigatePushAction(state, rootState) {
139
+ const { screen, params } = rewriteNavigationStateToParams(state);
140
+ return {
141
+ type: 'NAVIGATE',
142
+ target: rootState.key,
143
+ payload: {
144
+ name: screen,
145
+ params,
146
+ },
147
+ };
148
+ }
149
+ function getNavigateReplaceAction(state, parentState, lastNavigatorSupportingReplace = parentState) {
150
+ // We should always have at least one route in the state
151
+ const route = state.routes[state.routes.length - 1];
152
+ // Only these navigators support replace
153
+ if (parentState.type === 'stack' || parentState.type === 'tab') {
154
+ lastNavigatorSupportingReplace = parentState;
155
+ }
156
+ const currentRoute = parentState.routes.find((parentRoute) => parentRoute.name === route.name);
157
+ const routesAreEqual = parentState.routes[parentState.index] === currentRoute;
158
+ // If there is nested state and the routes are equal, we should keep going down the tree
159
+ if (route.state && routesAreEqual && currentRoute.state) {
160
+ return getNavigateReplaceAction(route.state, currentRoute.state, lastNavigatorSupportingReplace);
161
+ }
162
+ // Either we reached the bottom of the state or the point where the routes diverged
163
+ const { screen, params } = rewriteNavigationStateToParams(state);
164
+ return {
165
+ type: lastNavigatorSupportingReplace.type === 'stack' ? 'REPLACE' : 'JUMP_TO',
166
+ target: lastNavigatorSupportingReplace?.key,
167
+ payload: {
168
+ name: screen,
169
+ params,
170
+ },
171
+ };
192
172
  }
193
173
  //# sourceMappingURL=routing.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"routing.js","sourceRoot":"","sources":["../../src/global-state/routing.ts"],"names":[],"mappings":"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","sourcesContent":["import { CommonActions, getActionFromState, StackActions } from '@react-navigation/core';\nimport { TabActions } from '@react-navigation/native';\nimport * as Linking from 'expo-linking';\n\nimport type { RouterStore } from './router-store';\nimport { Href, resolveHref } from '../link/href';\nimport { resolve } from '../link/path';\nimport {\n NavigateAction,\n findTopRouteForTarget,\n getEarliestMismatchedRoute,\n getQualifiedStateForTopOfTargetState,\n isMovingToSiblingRoute,\n} from '../link/stateOperations';\nimport { hasUrlProtocolPrefix } from '../utils/url';\n\nfunction assertIsReady(store: RouterStore) {\n if (!store.navigationRef.isReady()) {\n throw new Error(\n 'Attempted to navigate before mounting the Root Layout component. Ensure the Root Layout component is rendering a Slot, or other navigator on the first render.'\n );\n }\n}\n\nexport function push(this: RouterStore, url: Href) {\n return this.linkTo(resolveHref(url));\n}\n\nexport function replace(this: RouterStore, url: Href) {\n return this.linkTo(resolveHref(url), 'REPLACE');\n}\n\nexport function goBack(this: RouterStore) {\n assertIsReady(this);\n this.navigationRef?.current?.goBack();\n}\n\nexport function canGoBack(this: RouterStore): boolean {\n // Return a default value here if the navigation hasn't mounted yet.\n // This can happen if the user calls `canGoBack` from the Root Layout route\n // before mounting a navigator. This behavior exists due to React Navigation being dynamically\n // constructed at runtime. We can get rid of this in the future if we use\n // the static configuration internally.\n if (!this.navigationRef.isReady()) {\n return false;\n }\n return this.navigationRef?.current?.canGoBack() ?? false;\n}\n\nexport function setParams(this: RouterStore, params: Record<string, string | number> = {}) {\n assertIsReady(this);\n return (this.navigationRef?.current?.setParams as any)(params);\n}\n\nexport function linkTo(this: RouterStore, href: string, event?: string) {\n if (hasUrlProtocolPrefix(href)) {\n Linking.openURL(href);\n return;\n }\n\n assertIsReady(this);\n const navigationRef = this.navigationRef.current;\n\n if (navigationRef == null) {\n throw new Error(\n \"Couldn't find a navigation object. Is your component inside NavigationContainer?\"\n );\n }\n\n if (!this.linking) {\n throw new Error('Attempted to link to route when no routes are present');\n }\n\n if (href === '..' || href === '../') {\n navigationRef.goBack();\n return;\n }\n\n if (href.startsWith('.')) {\n let base =\n this.linking.getPathFromState?.(navigationRef.getRootState(), {\n screens: [],\n preserveGroups: true,\n }) ?? '';\n\n if (base && !base.endsWith('/')) {\n base += '/..';\n }\n href = resolve(base, href);\n }\n\n const state = this.linking.getStateFromPath!(href, this.linking.config);\n\n if (!state) {\n console.error('Could not generate a valid navigation state for the given path: ' + href);\n return;\n }\n\n const rootState = navigationRef.getRootState();\n\n // Ensure simple operations are used when moving between siblings\n // in the same navigator. This ensures that the state is not reset.\n // TODO: We may need to apply this at a larger scale in the future.\n if (isMovingToSiblingRoute(rootState, state)) {\n // Can perform naive movements\n const knownOwnerState = getQualifiedStateForTopOfTargetState(rootState, state)!;\n const nextRoute = findTopRouteForTarget(state);\n // NOTE(EvanBacon): There's an issue where moving from \"a -> b\" is considered siblings:\n // a. index (initialRouteName=\"index\")\n // b. stack/index\n // However, the preservation approach doesn't work because it would be moving to a route with the same name.\n // The next check will see if the current focused route has the same name as the next route, if so, then fallback on\n // the default React Navigation logic.\n if (\n findTopRouteForTarget(\n // @ts-expect-error: stale types don't matter here\n rootState\n )?.name !== nextRoute.name\n ) {\n if (event === 'REPLACE') {\n if (knownOwnerState.type === 'tab') {\n navigationRef.dispatch(TabActions.jumpTo(nextRoute.name, nextRoute.params));\n } else {\n navigationRef.dispatch(StackActions.replace(nextRoute.name, nextRoute.params));\n }\n } else {\n // NOTE: Not sure if we should pop or push here...\n navigationRef.dispatch(CommonActions.navigate(nextRoute.name, nextRoute.params));\n }\n return;\n }\n }\n\n // TODO: Advanced movements across multiple navigators\n\n const action = getActionFromState(state, this.linking.config);\n if (action) {\n // Here we have a navigation action to a nested screen, where we should ideally replace.\n // This request can only be fulfilled if the target is an initial route.\n // First, check if the action is fully initial routes.\n // Then find the nearest mismatched route in the existing state.\n // Finally, use the correct navigator-based action to replace the nested screens.\n // NOTE(EvanBacon): A future version of this will involve splitting the navigation request so we replace as much as possible, then push the remaining screens to fulfill the request.\n if (event === 'REPLACE' && isAbsoluteInitialRoute(action)) {\n const earliest = getEarliestMismatchedRoute(rootState, action.payload);\n if (earliest) {\n if (earliest.type === 'stack') {\n navigationRef.dispatch(StackActions.replace(earliest.name, earliest.params));\n } else {\n navigationRef.dispatch(TabActions.jumpTo(earliest.name, earliest.params));\n }\n return;\n } else {\n // This should never happen because moving to the same route would be handled earlier\n // in the sibling operations.\n }\n }\n\n // Ignore the replace event here since replace across\n // navigators is not supported.\n navigationRef.dispatch(action);\n } else {\n navigationRef.reset(state);\n }\n}\n\n/** @returns `true` if the action is moving to the first screen of all the navigators in the action. */\nexport function isAbsoluteInitialRoute(\n action: ReturnType<typeof getActionFromState>\n): action is NavigateAction {\n if (action?.type !== 'NAVIGATE') {\n return false;\n }\n\n let next = action.payload.params;\n // iterate all child screens and bail out if any are not initial.\n while (next) {\n if (!isNavigationState(next)) {\n // Not sure when this would happen\n return false;\n }\n if (next.initial === true) {\n next = next.params;\n // return true;\n } else if (next.initial === false) {\n return false;\n }\n }\n\n return true;\n}\n\ntype NavStateParams = {\n params?: NavStateParams;\n path: string;\n initial: boolean;\n screen: string;\n state: unknown;\n};\n\nfunction isNavigationState(obj: any): obj is NavStateParams {\n return 'initial' in obj;\n}\n"]}
1
+ {"version":3,"file":"routing.js","sourceRoot":"","sources":["../../src/global-state/routing.ts"],"names":[],"mappings":"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","sourcesContent":["import { type NavigationAction, type NavigationState } from '@react-navigation/native';\nimport * as Linking from 'expo-linking';\n\nimport type { RouterStore } from './router-store';\nimport { ResultState } from '../fork/getStateFromPath';\nimport { Href, resolveHref } from '../link/href';\nimport { resolve } from '../link/path';\nimport { shouldLinkExternally } from '../utils/url';\n\nfunction assertIsReady(store: RouterStore) {\n if (!store.navigationRef.isReady()) {\n throw new Error(\n 'Attempted to navigate before mounting the Root Layout component. Ensure the Root Layout component is rendering a Slot, or other navigator on the first render.'\n );\n }\n}\n\nexport function push(this: RouterStore, url: Href) {\n return this.linkTo(resolveHref(url));\n}\n\nexport function replace(this: RouterStore, url: Href) {\n return this.linkTo(resolveHref(url), 'REPLACE');\n}\n\nexport function goBack(this: RouterStore) {\n assertIsReady(this);\n this.navigationRef?.current?.goBack();\n}\n\nexport function canGoBack(this: RouterStore): boolean {\n // Return a default value here if the navigation hasn't mounted yet.\n // This can happen if the user calls `canGoBack` from the Root Layout route\n // before mounting a navigator. This behavior exists due to React Navigation being dynamically\n // constructed at runtime. We can get rid of this in the future if we use\n // the static configuration internally.\n if (!this.navigationRef.isReady()) {\n return false;\n }\n return this.navigationRef?.current?.canGoBack() ?? false;\n}\n\nexport function setParams(this: RouterStore, params: Record<string, string | number> = {}) {\n assertIsReady(this);\n return (this.navigationRef?.current?.setParams as any)(params);\n}\n\nexport function linkTo(this: RouterStore, href: string, event?: string) {\n if (shouldLinkExternally(href)) {\n Linking.openURL(href);\n return;\n }\n\n assertIsReady(this);\n const navigationRef = this.navigationRef.current;\n\n if (navigationRef == null) {\n throw new Error(\n \"Couldn't find a navigation object. Is your component inside NavigationContainer?\"\n );\n }\n\n if (!this.linking) {\n throw new Error('Attempted to link to route when no routes are present');\n }\n\n if (href === '..' || href === '../') {\n navigationRef.goBack();\n return;\n }\n\n const rootState = navigationRef.getRootState();\n\n if (href.startsWith('.')) {\n // Resolve base path by merging the current segments with the params\n let base =\n this.routeInfo?.segments\n ?.map((segment) => {\n if (!segment.startsWith('[')) return segment;\n\n if (segment.startsWith('[...')) {\n segment = segment.slice(4, -1);\n const params = this.routeInfo?.params?.[segment];\n if (Array.isArray(params)) {\n return params.join('/');\n } else {\n return params?.split(',')?.join('/') ?? '';\n }\n } else {\n segment = segment.slice(1, -1);\n return this.routeInfo?.params?.[segment];\n }\n })\n .filter(Boolean)\n .join('/') ?? '/';\n\n if (!this.routeInfo?.isIndex) {\n base += '/..';\n }\n\n href = resolve(base, href);\n }\n\n const state = this.linking.getStateFromPath!(href, this.linking.config);\n\n if (!state || state.routes.length === 0) {\n console.error('Could not generate a valid navigation state for the given path: ' + href);\n return;\n }\n\n switch (event) {\n case 'REPLACE':\n return navigationRef.dispatch(getNavigateReplaceAction(state, rootState));\n default:\n return navigationRef.dispatch(getNavigatePushAction(state, rootState));\n }\n}\n\ntype NavigationParams = Partial<{\n screen: string;\n params: NavigationParams;\n}>;\n\nfunction rewriteNavigationStateToParams(\n state?: { routes: ResultState['routes'] },\n params: NavigationParams = {}\n) {\n if (!state) return params;\n // We Should always have at least one route in the state\n const lastRoute = state.routes[state.routes.length - 1]!;\n params.screen = lastRoute.name;\n // Weirdly, this always needs to be an object. If it's undefined, it won't work.\n params.params = lastRoute.params ? JSON.parse(JSON.stringify(lastRoute.params)) : {};\n\n if (lastRoute.state) {\n rewriteNavigationStateToParams(lastRoute.state, params.params);\n }\n\n return JSON.parse(JSON.stringify(params));\n}\n\nfunction getNavigatePushAction(state: ResultState, rootState: NavigationState) {\n const { screen, params } = rewriteNavigationStateToParams(state);\n return {\n type: 'NAVIGATE',\n target: rootState.key,\n payload: {\n name: screen,\n params,\n },\n };\n}\n\nfunction getNavigateReplaceAction(\n state: ResultState,\n parentState: NavigationState,\n lastNavigatorSupportingReplace: NavigationState = parentState\n): NavigationAction {\n // We should always have at least one route in the state\n const route = state.routes[state.routes.length - 1]!;\n\n // Only these navigators support replace\n if (parentState.type === 'stack' || parentState.type === 'tab') {\n lastNavigatorSupportingReplace = parentState;\n }\n\n const currentRoute = parentState.routes.find((parentRoute) => parentRoute.name === route.name);\n const routesAreEqual = parentState.routes[parentState.index] === currentRoute;\n\n // If there is nested state and the routes are equal, we should keep going down the tree\n if (route.state && routesAreEqual && currentRoute.state) {\n return getNavigateReplaceAction(\n route.state,\n currentRoute.state as any,\n lastNavigatorSupportingReplace\n );\n }\n\n // Either we reached the bottom of the state or the point where the routes diverged\n const { screen, params } = rewriteNavigationStateToParams(state);\n\n return {\n type: lastNavigatorSupportingReplace.type === 'stack' ? 'REPLACE' : 'JUMP_TO',\n target: lastNavigatorSupportingReplace?.key,\n payload: {\n name: screen,\n params,\n },\n };\n}\n"]}
@@ -144,19 +144,19 @@ function isTruthy(value) {
144
144
  function HeadNative(props) {
145
145
  const isFocused = (0, core_1.useIsFocused)();
146
146
  if (!isFocused) {
147
- return react_1.default.createElement(UnfocusedHead, null);
147
+ return <UnfocusedHead />;
148
148
  }
149
- return react_1.default.createElement(FocusedHead, { ...props });
149
+ return <FocusedHead {...props}/>;
150
150
  }
151
151
  function UnfocusedHead(props) {
152
152
  const { children } = useMetaChildren(props.children);
153
- return react_1.default.createElement(react_1.default.Fragment, null, children);
153
+ return <>{children}</>;
154
154
  }
155
155
  function FocusedHead(props) {
156
156
  const { metaChildren, children } = useMetaChildren(props.children);
157
157
  const activity = useActivityFromMetaChildren(metaChildren);
158
158
  useRegisterCurrentActivity(activity);
159
- return react_1.default.createElement(react_1.default.Fragment, null, children);
159
+ return <>{children}</>;
160
160
  }
161
161
  // segments => activity
162
162
  const activities = new Map();
@@ -1 +1 @@
1
- {"version":3,"file":"ExpoHead.ios.js","sourceRoot":"","sources":["../../src/head/ExpoHead.ios.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useIsFocused } from '@react-navigation/core';\nimport React from 'react';\n\nimport { ExpoHead, UserActivity } from './ExpoHeadModule';\nimport { getStaticUrlFromExpoRouter } from './url';\nimport { useLocalSearchParams, useUnstableGlobalHref, usePathname, useSegments } from '../hooks';\n\nfunction urlToId(url: string) {\n return url.replace(/[^a-zA-Z0-9]/g, '-');\n}\n\nfunction getLastSegment(path: string) {\n // Remove the extension\n const lastSegment = path.split('/').pop() ?? '';\n return lastSegment.replace(/\\.[^/.]+$/, '').split('?')[0];\n}\n\n// TODO: Use Head Provider to collect all props so only one Head is rendered for a given route.\n\nfunction useAddressableLink() {\n const pathname = useUnstableGlobalHref();\n const params = useLocalSearchParams<any>();\n const url = getStaticUrlFromExpoRouter(pathname);\n return { url, pathname, params };\n}\n\ntype MetaNode =\n | React.ReactPortal\n | React.ReactElement<unknown, string | React.JSXElementConstructor<any>>;\n\nfunction useMetaChildren(children: React.ReactNode) {\n return React.useMemo(() => {\n const renderableChildren: React.ReactNode[] = [];\n const metaChildren: MetaNode[] = [];\n\n React.Children.forEach(children, (child) => {\n if (!React.isValidElement(child)) {\n return;\n }\n if (typeof child.type === 'string') {\n metaChildren.push(child);\n } else {\n renderableChildren.push(child);\n }\n });\n\n return { children: renderableChildren, metaChildren };\n }, [children]);\n}\n\ntype SerializedMeta = {\n type: string;\n props: { [key: string]: string | undefined };\n};\n\nfunction serializedMetaChildren(meta: MetaNode[]): SerializedMeta[] {\n const validMeta = meta.filter((child) => child.type === 'meta' || child.type === 'title');\n\n return validMeta.map((child) => {\n if (child.type === 'title') {\n return {\n type: 'title',\n props: {\n children: typeof child.props.children === 'string' ? child.props.children : undefined,\n },\n };\n }\n return {\n type: 'meta',\n props: {\n property: typeof child.props.property === 'string' ? child.props.property : undefined,\n content: typeof child.props.content === 'string' ? child.props.content : undefined,\n },\n };\n });\n}\n\nfunction useActivityFromMetaChildren(meta: MetaNode[]) {\n const { url: href, pathname } = useAddressableLink();\n\n const previousMeta = React.useRef<SerializedMeta[]>([]);\n const cachedActivity = React.useRef<Partial<UserActivity>>({});\n\n const sortedMeta = React.useMemo(() => serializedMetaChildren(meta), [meta]);\n\n const url = React.useMemo(() => {\n const urlMeta = sortedMeta.find(\n (child) => child.type === 'meta' && child.props.property === 'og:url'\n );\n\n if (urlMeta) {\n // Support =`/foo/bar` -> `https://example.com/foo/bar`\n if (urlMeta.props.content?.startsWith('/')) {\n return getStaticUrlFromExpoRouter(urlMeta.props.content);\n }\n return urlMeta.props.content;\n }\n return href;\n }, [sortedMeta, href]);\n\n const title = React.useMemo(() => {\n const titleTag = sortedMeta.find((child) => child.type === 'title');\n if (titleTag) {\n return titleTag.props.children ?? '';\n }\n const titleMeta = sortedMeta.find(\n (child) => child.type === 'meta' && child.props.property === 'og:title'\n );\n if (titleMeta) {\n return titleMeta.props.content ?? '';\n }\n\n return getLastSegment(pathname);\n }, [sortedMeta, pathname]);\n\n const activity = React.useMemo(() => {\n if (\n !!previousMeta.current &&\n !!cachedActivity.current &&\n deepObjectCompare(previousMeta.current, sortedMeta)\n ) {\n return cachedActivity.current;\n }\n previousMeta.current = sortedMeta;\n\n const userActivity: Partial<UserActivity> = {};\n\n sortedMeta.forEach((child) => {\n if (\n // <meta />\n child.type === 'meta'\n ) {\n const { property, content } = child.props;\n\n switch (property) {\n case 'og:description':\n userActivity.description = content;\n break;\n // Custom properties\n case 'expo:handoff':\n userActivity.isEligibleForHandoff = isTruthy(content);\n break;\n case 'expo:spotlight':\n userActivity.isEligibleForSearch = isTruthy(content);\n break;\n }\n\n // // <meta name=\"keywords\" content=\"foo,bar,baz\" />\n // if ([\"keywords\"].includes(name)) {\n // userActivity.keywords = Array.isArray(content)\n // ? content\n // : content.split(\",\");\n // }\n }\n });\n\n cachedActivity.current = userActivity;\n return userActivity;\n }, [meta, pathname, href]);\n\n const parsedActivity: UserActivity = {\n keywords: [title],\n ...activity,\n title,\n webpageURL: url,\n activityType: ExpoHead!.activities.INDEXED_ROUTE,\n userInfo: {\n // TODO: This may need to be versioned in the future, e.g. `_v1` if we change the format.\n href,\n },\n };\n\n return parsedActivity;\n}\n\nfunction isTruthy(value: any): boolean {\n return [true, 'true'].includes(value);\n}\n\nfunction HeadNative(props: { children?: React.ReactNode }) {\n const isFocused = useIsFocused();\n if (!isFocused) {\n return <UnfocusedHead />;\n }\n return <FocusedHead {...props} />;\n}\n\nfunction UnfocusedHead(props: { children?: React.ReactNode }): JSX.Element {\n const { children } = useMetaChildren(props.children);\n return <>{children}</>;\n}\n\nfunction FocusedHead(props: { children?: React.ReactNode }): JSX.Element {\n const { metaChildren, children } = useMetaChildren(props.children);\n const activity = useActivityFromMetaChildren(metaChildren);\n useRegisterCurrentActivity(activity);\n return <>{children}</>;\n}\n\n// segments => activity\nconst activities: Map<string, UserActivity> = new Map();\n\nfunction useRegisterCurrentActivity(activity: UserActivity) {\n // ID is tied to Expo Router and agnostic of URLs to ensure dynamic parameters are not considered.\n // Using all segments ensures that cascading routes are considered.\n const activityId = urlToId(usePathname() || '/');\n const cascadingId = urlToId(useSegments().join('-') || '-');\n const activityIds = Array.from(activities.keys());\n const cascadingActivity: UserActivity = React.useMemo(() => {\n // Get all nested activities together, then update the id to match the current pathname.\n // This enables cases like `/user/[name]/post/[id]` to match all nesting, while still having a URL-specific ID, i.e. `/user/evanbacon/post/123`\n const cascadingActivity = activities.has(cascadingId)\n ? {\n ...activities.get(cascadingId),\n ...activity,\n id: activityId,\n }\n : {\n ...activity,\n id: activityId,\n };\n activities.set(cascadingId, cascadingActivity);\n\n return cascadingActivity;\n }, [cascadingId, activityId, activity, activityIds]);\n\n const previousActivity = React.useRef<UserActivity | null>(null);\n\n React.useEffect(() => {\n if (!cascadingActivity) {\n return () => {};\n }\n if (\n !!previousActivity.current &&\n deepObjectCompare(previousActivity.current, cascadingActivity)\n ) {\n return () => {};\n }\n\n previousActivity.current = cascadingActivity;\n if (!cascadingActivity.id) {\n throw new Error('Activity must have an ID');\n }\n\n // If no features are enabled, then skip registering the activity\n if (cascadingActivity.isEligibleForHandoff || cascadingActivity.isEligibleForSearch) {\n ExpoHead?.createActivity(cascadingActivity);\n }\n\n return () => {};\n }, [cascadingActivity]);\n\n React.useEffect(() => {\n return () => {\n if (activityId) {\n ExpoHead?.suspendActivity(activityId);\n }\n };\n }, [activityId]);\n}\n\nfunction deepObjectCompare(a: any, b: any) {\n if (typeof a !== typeof b) {\n return false;\n }\n if (typeof a === 'object') {\n if (Array.isArray(a) !== Array.isArray(b)) {\n return false;\n }\n if (Array.isArray(a)) {\n if (a.length !== b.length) {\n return false;\n }\n return a.every((item, index) => deepObjectCompare(item, b[index]));\n }\n // handle null\n if (a === null || b === null) {\n return a === b;\n }\n const aKeys = Object.keys(a);\n const bKeys = Object.keys(b);\n if (aKeys.length !== bKeys.length) {\n return false;\n }\n return aKeys.every((key) => deepObjectCompare(a[key], b[key]));\n }\n return a === b;\n}\n\nHeadNative.Provider = React.Fragment;\n\nfunction HeadShim(props: { children?: React.ReactNode }) {\n return null;\n}\n\nHeadShim.Provider = React.Fragment;\n\n// Native Head is only enabled in bare iOS apps.\nexport const Head: ((props: { children?: React.ReactNode }) => React.ReactNode) & {\n Provider: React.ComponentType;\n} = ExpoHead ? HeadNative : HeadShim;\n"]}
1
+ {"version":3,"file":"ExpoHead.ios.js","sourceRoot":"","sources":["../../src/head/ExpoHead.ios.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useIsFocused } from '@react-navigation/core';\nimport React from 'react';\n\nimport { ExpoHead, UserActivity } from './ExpoHeadModule';\nimport { getStaticUrlFromExpoRouter } from './url';\nimport { useLocalSearchParams, useUnstableGlobalHref, usePathname, useSegments } from '../hooks';\n\nfunction urlToId(url: string) {\n return url.replace(/[^a-zA-Z0-9]/g, '-');\n}\n\nfunction getLastSegment(path: string) {\n // Remove the extension\n const lastSegment = path.split('/').pop() ?? '';\n return lastSegment.replace(/\\.[^/.]+$/, '').split('?')[0];\n}\n\n// TODO: Use Head Provider to collect all props so only one Head is rendered for a given route.\n\nfunction useAddressableLink() {\n const pathname = useUnstableGlobalHref();\n const params = useLocalSearchParams<any>();\n const url = getStaticUrlFromExpoRouter(pathname);\n return { url, pathname, params };\n}\n\ntype MetaNode =\n | React.ReactPortal\n | React.ReactElement<unknown, string | React.JSXElementConstructor<any>>;\n\nfunction useMetaChildren(children: React.ReactNode) {\n return React.useMemo(() => {\n const renderableChildren: React.ReactNode[] = [];\n const metaChildren: MetaNode[] = [];\n\n React.Children.forEach(children, (child) => {\n if (!React.isValidElement(child)) {\n return;\n }\n if (typeof child.type === 'string') {\n metaChildren.push(child);\n } else {\n renderableChildren.push(child);\n }\n });\n\n return { children: renderableChildren, metaChildren };\n }, [children]);\n}\n\ntype SerializedMeta = {\n type: string;\n props: { [key: string]: string | undefined };\n};\n\nfunction serializedMetaChildren(meta: MetaNode[]): SerializedMeta[] {\n const validMeta = meta.filter((child) => child.type === 'meta' || child.type === 'title');\n\n return validMeta.map((child) => {\n if (child.type === 'title') {\n return {\n type: 'title',\n props: {\n children: typeof child.props.children === 'string' ? child.props.children : undefined,\n },\n };\n }\n return {\n type: 'meta',\n props: {\n property: typeof child.props.property === 'string' ? child.props.property : undefined,\n content: typeof child.props.content === 'string' ? child.props.content : undefined,\n },\n };\n });\n}\n\nfunction useActivityFromMetaChildren(meta: MetaNode[]) {\n const { url: href, pathname } = useAddressableLink();\n\n const previousMeta = React.useRef<SerializedMeta[]>([]);\n const cachedActivity = React.useRef<Partial<UserActivity>>({});\n\n const sortedMeta = React.useMemo(() => serializedMetaChildren(meta), [meta]);\n\n const url = React.useMemo(() => {\n const urlMeta = sortedMeta.find(\n (child) => child.type === 'meta' && child.props.property === 'og:url'\n );\n\n if (urlMeta) {\n // Support =`/foo/bar` -> `https://example.com/foo/bar`\n if (urlMeta.props.content?.startsWith('/')) {\n return getStaticUrlFromExpoRouter(urlMeta.props.content);\n }\n return urlMeta.props.content;\n }\n return href;\n }, [sortedMeta, href]);\n\n const title = React.useMemo(() => {\n const titleTag = sortedMeta.find((child) => child.type === 'title');\n if (titleTag) {\n return titleTag.props.children ?? '';\n }\n const titleMeta = sortedMeta.find(\n (child) => child.type === 'meta' && child.props.property === 'og:title'\n );\n if (titleMeta) {\n return titleMeta.props.content ?? '';\n }\n\n return getLastSegment(pathname);\n }, [sortedMeta, pathname]);\n\n const activity = React.useMemo(() => {\n if (\n !!previousMeta.current &&\n !!cachedActivity.current &&\n deepObjectCompare(previousMeta.current, sortedMeta)\n ) {\n return cachedActivity.current;\n }\n previousMeta.current = sortedMeta;\n\n const userActivity: Partial<UserActivity> = {};\n\n sortedMeta.forEach((child) => {\n if (\n // <meta />\n child.type === 'meta'\n ) {\n const { property, content } = child.props;\n\n switch (property) {\n case 'og:description':\n userActivity.description = content;\n break;\n // Custom properties\n case 'expo:handoff':\n userActivity.isEligibleForHandoff = isTruthy(content);\n break;\n case 'expo:spotlight':\n userActivity.isEligibleForSearch = isTruthy(content);\n break;\n }\n\n // // <meta name=\"keywords\" content=\"foo,bar,baz\" />\n // if ([\"keywords\"].includes(name)) {\n // userActivity.keywords = Array.isArray(content)\n // ? content\n // : content.split(\",\");\n // }\n }\n });\n\n cachedActivity.current = userActivity;\n return userActivity;\n }, [meta, pathname, href]);\n\n const parsedActivity: UserActivity = {\n keywords: [title],\n ...activity,\n title,\n webpageURL: url,\n activityType: ExpoHead!.activities.INDEXED_ROUTE,\n userInfo: {\n // TODO: This may need to be versioned in the future, e.g. `_v1` if we change the format.\n href,\n },\n };\n\n return parsedActivity;\n}\n\nfunction isTruthy(value: any): boolean {\n return [true, 'true'].includes(value);\n}\n\nfunction HeadNative(props: { children?: React.ReactNode }) {\n const isFocused = useIsFocused();\n if (!isFocused) {\n return <UnfocusedHead />;\n }\n return <FocusedHead {...props} />;\n}\n\nfunction UnfocusedHead(props: { children?: React.ReactNode }): JSX.Element {\n const { children } = useMetaChildren(props.children);\n return <>{children}</>;\n}\n\nfunction FocusedHead(props: { children?: React.ReactNode }): JSX.Element {\n const { metaChildren, children } = useMetaChildren(props.children);\n const activity = useActivityFromMetaChildren(metaChildren);\n useRegisterCurrentActivity(activity);\n return <>{children}</>;\n}\n\n// segments => activity\nconst activities: Map<string, UserActivity> = new Map();\n\nfunction useRegisterCurrentActivity(activity: UserActivity) {\n // ID is tied to Expo Router and agnostic of URLs to ensure dynamic parameters are not considered.\n // Using all segments ensures that cascading routes are considered.\n const activityId = urlToId(usePathname() || '/');\n const cascadingId = urlToId(useSegments().join('-') || '-');\n const activityIds = Array.from(activities.keys());\n const cascadingActivity: UserActivity = React.useMemo(() => {\n // Get all nested activities together, then update the id to match the current pathname.\n // This enables cases like `/user/[name]/post/[id]` to match all nesting, while still having a URL-specific ID, i.e. `/user/evanbacon/post/123`\n const cascadingActivity = activities.has(cascadingId)\n ? {\n ...activities.get(cascadingId),\n ...activity,\n id: activityId,\n }\n : {\n ...activity,\n id: activityId,\n };\n activities.set(cascadingId, cascadingActivity);\n\n return cascadingActivity;\n }, [cascadingId, activityId, activity, activityIds]);\n\n const previousActivity = React.useRef<UserActivity | null>(null);\n\n React.useEffect(() => {\n if (!cascadingActivity) {\n return () => {};\n }\n if (\n !!previousActivity.current &&\n deepObjectCompare(previousActivity.current, cascadingActivity)\n ) {\n return () => {};\n }\n\n previousActivity.current = cascadingActivity;\n if (!cascadingActivity.id) {\n throw new Error('Activity must have an ID');\n }\n\n // If no features are enabled, then skip registering the activity\n if (cascadingActivity.isEligibleForHandoff || cascadingActivity.isEligibleForSearch) {\n ExpoHead?.createActivity(cascadingActivity);\n }\n\n return () => {};\n }, [cascadingActivity]);\n\n React.useEffect(() => {\n return () => {\n if (activityId) {\n ExpoHead?.suspendActivity(activityId);\n }\n };\n }, [activityId]);\n}\n\nfunction deepObjectCompare(a: any, b: any) {\n if (typeof a !== typeof b) {\n return false;\n }\n if (typeof a === 'object') {\n if (Array.isArray(a) !== Array.isArray(b)) {\n return false;\n }\n if (Array.isArray(a)) {\n if (a.length !== b.length) {\n return false;\n }\n return a.every((item, index) => deepObjectCompare(item, b[index]));\n }\n // handle null\n if (a === null || b === null) {\n return a === b;\n }\n const aKeys = Object.keys(a);\n const bKeys = Object.keys(b);\n if (aKeys.length !== bKeys.length) {\n return false;\n }\n return aKeys.every((key) => deepObjectCompare(a[key], b[key]));\n }\n return a === b;\n}\n\nHeadNative.Provider = React.Fragment;\n\nfunction HeadShim(props: { children?: React.ReactNode }) {\n return null;\n}\n\nHeadShim.Provider = React.Fragment;\n\n// Native Head is only enabled in bare iOS apps.\nexport const Head: ((props: { children?: React.ReactNode }) => React.ReactNode) & {\n Provider: React.ComponentType;\n} = ExpoHead ? HeadNative : HeadShim;\n"]}