-
Notifications
You must be signed in to change notification settings - Fork 685
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Supplant MagentoRouteHandler (#1966)
* Supplant MagentoRouteHandler with Routes * Handle PR feedback * Address PR feedback * Export error strings * Fix unit tests * Remove client-only route consideration
- Loading branch information
1 parent
0f91cd4
commit d0164ba
Showing
14 changed files
with
458 additions
and
36 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
const addToCache = async (...urls) => { | ||
if (!window.caches) { | ||
throw new Error( | ||
'Current environment does not support CacheStorage at window.caches.' | ||
); | ||
} | ||
|
||
const cache = await window.caches.open( | ||
`workbox-runtime-${location.origin}/` | ||
); | ||
|
||
await cache.addAll(urls); | ||
}; | ||
|
||
export default addToCache; |
57 changes: 57 additions & 0 deletions
57
packages/peregrine/lib/talons/MagentoRoute/getRouteComponent.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import resolveUnknownRoute from '../../Router/resolveUnknownRoute'; | ||
|
||
export const INTERNAL_ERROR = 'INTERNAL_ERROR'; | ||
export const NOT_FOUND = 'NOT_FOUND'; | ||
|
||
const getRouteComponent = async (apiBase, pathname) => { | ||
// At build time, `fetchRootComponent` is injected as a global. | ||
// Depending on the environment, this global will be either an | ||
// ES module with a `default` property, or a plain CJS module. | ||
const fetchRoot = | ||
'default' in fetchRootComponent | ||
? fetchRootComponent.default | ||
: fetchRootComponent; | ||
|
||
try { | ||
// try to resolve the route | ||
// if this throws, we essentially have a 500 Internal Error | ||
const resolvedRoute = await resolveUnknownRoute({ | ||
apiBase, | ||
route: pathname | ||
}); | ||
|
||
// urlResolver query returns null if a route can't be found | ||
if (!resolvedRoute) { | ||
throw new Error('404'); | ||
} | ||
|
||
const { type, id } = resolvedRoute; | ||
// if resolution and destructuring succeed but return no match | ||
// then we have a straightforward 404 Not Found | ||
if (!type || !id) { | ||
throw new Error('404'); | ||
} | ||
|
||
// at this point we should have a matching RootComponent | ||
// if this throws, we essentially have a 500 Internal Error | ||
const component = await fetchRoot(type); | ||
|
||
// associate the matching RootComponent with this location | ||
return { | ||
component, | ||
id, | ||
pathname, | ||
type | ||
}; | ||
} catch (e) { | ||
const routeError = e.message === '404' ? NOT_FOUND : INTERNAL_ERROR; | ||
|
||
console.error(e); | ||
|
||
// we don't have a matching RootComponent, but we've checked for one | ||
// so associate the appropriate error case with this location | ||
return { pathname, routeError }; | ||
} | ||
}; | ||
|
||
export default getRouteComponent; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export { INTERNAL_ERROR, NOT_FOUND } from './getRouteComponent'; | ||
export { useMagentoRoute } from './useMagentoRoute'; |
61 changes: 61 additions & 0 deletions
61
packages/peregrine/lib/talons/MagentoRoute/useMagentoRoute.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
import { useEffect, useRef, useState } from 'react'; | ||
import { useLocation } from 'react-router-dom'; | ||
import { useApolloClient } from '@apollo/react-hooks'; | ||
|
||
import addToCache from './addToCache'; | ||
import getRouteComponent from './getRouteComponent'; | ||
|
||
const IS_LOADING = { isLoading: true }; | ||
|
||
export const useMagentoRoute = () => { | ||
const [componentMap, setComponentMap] = useState(new Map()); | ||
const { apiBase } = useApolloClient(); | ||
const { pathname } = useLocation(); | ||
const isMountedRef = useRef(false); | ||
|
||
const routeData = componentMap.get(pathname); | ||
|
||
// ask Magento for a RootComponent that matches the current pathname | ||
useEffect(() => { | ||
// avoid asking if we already know the answer | ||
const isKnown = componentMap.has(pathname); | ||
|
||
// ask again following a prior failure | ||
const isNotFound = isKnown && componentMap.get(pathname).id === -1; | ||
const shouldReload = isNotFound && navigator.onLine; | ||
|
||
if (!isKnown || shouldReload) { | ||
getRouteComponent(apiBase, pathname).then( | ||
({ component, id, pathname, routeError }) => { | ||
// avoid setting state if unmounted | ||
if (!isMountedRef.current) { | ||
return; | ||
} | ||
|
||
// add the pathname to the browser cache | ||
addToCache(pathname); | ||
|
||
// then add the pathname and result to local state | ||
setComponentMap(prevMap => { | ||
const nextMap = new Map(prevMap); | ||
const nextValue = routeError | ||
? { hasError: true, routeError } | ||
: { component, id }; | ||
|
||
return nextMap.set(pathname, nextValue); | ||
}); | ||
} | ||
); | ||
} | ||
}, [apiBase, componentMap, pathname]); | ||
|
||
useEffect(() => { | ||
isMountedRef.current = true; | ||
|
||
return () => { | ||
isMountedRef.current = false; | ||
}; | ||
}, []); | ||
|
||
return routeData || IS_LOADING; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.