UNPKG

@embrace-io/web-sdk

Version:
1 lines 3.62 kB
{"version":3,"file":"withEmbraceRouting.cjs","names":[],"sources":["../../../../../../src/instrumentations/navigation/NavigationInstrumentation/react/reactRouterV6Declarative/withEmbraceRouting.ts"],"sourcesContent":["import hoistNonReactStatics from 'hoist-non-react-statics';\nimport type React from 'react';\nimport { createElement } from 'react';\nimport type { Route } from '../../../../../api-page/index.ts';\nimport { page } from '../../../../../api-page/index.ts';\nimport type { RoutesFunctionalComponentReturn } from './types.ts';\n\n// Routes can be nested, we need to traverse the routeContext to find the last route\nconst getLastRoute = (\n matchedComponent: RoutesFunctionalComponentReturn,\n lastRoute: Route | null,\n): Route | null => {\n if (!matchedComponent.props.match?.route) {\n return null;\n }\n\n const childPath = matchedComponent.props.match.route.path;\n const path =\n lastRoute && !childPath.startsWith('/')\n ? `${lastRoute.path}/${childPath}`\n : childPath;\n\n if (matchedComponent.props.routeContext?.outlet) {\n return getLastRoute(matchedComponent.props.routeContext.outlet, {\n path,\n url: matchedComponent.props.match.pathname,\n });\n }\n\n return {\n path,\n url: matchedComponent.props.match.pathname,\n };\n};\n\nexport const withEmbraceRouting = <P extends object>(\n WrappedComponent: React.FunctionComponent<P>,\n) => {\n const RoutesWithEmbraceRouting: React.FC<P> = (props: P) => {\n /**\n * React-router v6+ implementation is very different from v5\n * It doesn't have a <Switch> component that injects props into <Route>\n * Instead, it has <Routes> which internally calculates the matched route\n * and returns it as a children, <Route> cannot be wrapped since it requires all children to be a <Route> component\n * here we rely on that matching to get the current route.\n * It's not ideal to rely on internal implementation details, but it's the easier way of getting the current route\n * without having to manually match it or using hooks on each children component\n *\n * See: https://github.com/remix-run/react-router/blob/main/packages/react-router/lib/hooks.tsx#L553\n */\n const matchedComponent = WrappedComponent(\n props,\n ) as unknown as RoutesFunctionalComponentReturn;\n\n if (matchedComponent.props.match?.route) {\n const lastRoute = getLastRoute(matchedComponent, null);\n if (lastRoute) {\n page.setCurrentRoute(lastRoute);\n }\n }\n\n return createElement<P>(WrappedComponent, props);\n };\n\n // Keep wrapped component metadata\n RoutesWithEmbraceRouting.displayName = `withEmbraceRouting(${WrappedComponent.displayName || WrappedComponent.name || 'Component'})`;\n hoistNonReactStatics(RoutesWithEmbraceRouting, WrappedComponent);\n\n return RoutesWithEmbraceRouting;\n};\n"],"mappings":";;;;;;;AAQA,MAAM,gBACJ,kBACA,cACiB;CACjB,IAAI,CAAC,iBAAiB,MAAM,OAAO,OACjC,OAAO;CAGT,MAAM,YAAY,iBAAiB,MAAM,MAAM,MAAM;CACrD,MAAM,OACJ,aAAa,CAAC,UAAU,WAAW,GAAG,IAClC,GAAG,UAAU,KAAK,GAAG,cACrB;CAEN,IAAI,iBAAiB,MAAM,cAAc,QACvC,OAAO,aAAa,iBAAiB,MAAM,aAAa,QAAQ;EAC9D;EACA,KAAK,iBAAiB,MAAM,MAAM;CACpC,CAAC;CAGH,OAAO;EACL;EACA,KAAK,iBAAiB,MAAM,MAAM;CACpC;AACF;AAEA,MAAa,sBACX,qBACG;CACH,MAAM,4BAAyC,UAAa;;;;;;;;;;;;EAY1D,MAAM,mBAAmB,iBACvB,KACF;EAEA,IAAI,iBAAiB,MAAM,OAAO,OAAO;GACvC,MAAM,YAAY,aAAa,kBAAkB,IAAI;GACrD,IAAI,WACF,yBAAA,KAAK,gBAAgB,SAAS;EAElC;EAEA,QAAA,GAAA,MAAA,cAAA,CAAwB,kBAAkB,KAAK;CACjD;CAGA,yBAAyB,cAAc,sBAAsB,iBAAiB,eAAe,iBAAiB,QAAQ,YAAY;CAClI,CAAA,GAAA,wBAAA,QAAA,CAAqB,0BAA0B,gBAAgB;CAE/D,OAAO;AACT"}