@buoy-gg/route-events 7.0.63 → 7.0.64
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.
- package/README.md +9 -0
- package/lib/commonjs/RouteObserver.js +1 -1
- package/lib/commonjs/browserRouteRegistry.js +1 -1
- package/lib/commonjs/browserRoutes.js +1 -1
- package/lib/commonjs/components/NavigationStack.js +2 -2
- package/lib/commonjs/components/RouteEventExpandedContent.js +1 -1
- package/lib/commonjs/components/RoutesSitemap.js +4 -2
- package/lib/commonjs/expoRouterStore.js +1 -1
- package/lib/commonjs/index.js +1 -1
- package/lib/commonjs/useNavigationStack.js +1 -1
- package/lib/commonjs/utils/safeReactNavigation.js +1 -1
- package/lib/module/RouteObserver.js +1 -1
- package/lib/module/browserRouteRegistry.js +1 -1
- package/lib/module/browserRoutes.js +1 -1
- package/lib/module/components/NavigationStack.js +2 -2
- package/lib/module/components/RouteEventExpandedContent.js +1 -1
- package/lib/module/components/RoutesSitemap.js +4 -2
- package/lib/module/expoRouterStore.js +1 -1
- package/lib/module/index.js +1 -1
- package/lib/module/useNavigationStack.js +1 -1
- package/lib/module/utils/safeReactNavigation.js +1 -1
- package/lib/typescript/RouteObserver.d.ts +2 -0
- package/lib/typescript/browserRouteRegistry.d.ts +2 -0
- package/lib/typescript/index.d.ts +1 -1
- package/lib/web/index.mjs +6 -4
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -25,3 +25,12 @@ The [Routes guide](https://buoy.gg/buoy/latest/docs/tools/routes) covers setup,
|
|
|
25
25
|
---
|
|
26
26
|
|
|
27
27
|
<sub>Part of <a href="https://buoy.gg">Buoy</a>, developer tools that live inside your app. Proprietary software. © Buoy LLC. <a href="https://buoy.gg/terms">Terms</a></sub>
|
|
28
|
+
|
|
29
|
+
### Angular Router
|
|
30
|
+
|
|
31
|
+
Use `connectBuoyRouter` from `@buoy-gg/angular/router` in the lazy setup.
|
|
32
|
+
It reads route names, params, and matched paths.
|
|
33
|
+
It also fills the sitemap from Angular's route list.
|
|
34
|
+
Go calls Angular Router. It asks for path params.
|
|
35
|
+
Call the returned stop function when the app stops.
|
|
36
|
+
Raw URL capture still works without this adapter.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.routeObserver=exports.RouteObserver=void 0;class RouteObserver{listeners=new Set;emit(e){this.listeners.forEach(r=>{try{r(e)}catch(t){console.error("[RouteObserver] Error in listener:",t)}})}addListener(e){this.listeners.add(e);return()=>this.listeners.delete(e)}removeListener(e){this.listeners.delete(e)}}exports.RouteObserver=RouteObserver;const routeObserver=exports.routeObserver=new RouteObserver;
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.routeObserver=exports.RouteObserver=void 0;class RouteObserver{listeners=new Set;emit(e){this.listeners.forEach(r=>{try{r(e)}catch(t){console.error("[Buoy]","[RouteObserver] Error in listener:",t)}})}addListener(e){this.listeners.add(e);return()=>this.listeners.delete(e)}removeListener(e){this.listeners.delete(e)}}exports.RouteObserver=RouteObserver;const routeObserver=exports.routeObserver=new RouteObserver;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.getBrowserRouteInfo=getBrowserRouteInfo;exports.getBrowserRoutePaths=getBrowserRoutePaths;exports.getBrowserRoutesUpdatedAt=getBrowserRoutesUpdatedAt;exports.registerBrowserRoutes=registerBrowserRoutes;const declared=new Map;let updatedAt=null;function registerBrowserRoutes(
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.claimBrowserRouteEvents=claimBrowserRouteEvents;exports.getBrowserRouteInfo=getBrowserRouteInfo;exports.getBrowserRoutePaths=getBrowserRoutePaths;exports.getBrowserRoutesUpdatedAt=getBrowserRoutesUpdatedAt;exports.hasBrowserRouteEventSource=hasBrowserRouteEventSource;exports.registerBrowserRoutes=registerBrowserRoutes;const declared=new Map;let updatedAt=null;function registerBrowserRoutes(e){for(const t of e)declared.set(t,(declared.get(t)??0)+1);updatedAt=Date.now();let s=true;return()=>{if(!s)return;s=false;for(const t of e){const n=(declared.get(t)??1)-1;if(n)declared.set(t,n);else declared.delete(t)}updatedAt=Date.now()}}function getBrowserRoutePaths(){return[...declared.keys()]}function getBrowserRoutesUpdatedAt(){return updatedAt}function getBrowserRouteInfo(e){const s={segments:e.split("/").filter(Boolean),params:{}};const t=getBrowserRoutePaths();if(t.includes(e))return s;for(const n of t){const u=n.split("/").filter(Boolean);const c=[];const p=u.map(r=>{const o=/^\[(\.\.\.)?([^\]]+)\]$/.exec(r);if(!o)return r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");c.push({name:o[2],deep:!!o[1]});return o[1]?"(.+)":"([^/]+)"});const a=new RegExp("^/"+p.join("/")+"/?$").exec(e);if(!a)continue;const i=r=>{try{return decodeURIComponent(r)}catch{return r}};const f={};c.forEach(({name:r,deep:o},d)=>{const l=a[d+1];f[r]=o?l.split("/").map(i):i(l)});return{segments:u,params:f}}return s}let eventSources=0;function claimBrowserRouteEvents(){eventSources++;let e=true;return()=>{if(e){e=false;eventSources--}}}function hasBrowserRouteEventSource(){return eventSources>0}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.startBrowserRouteCapture=startBrowserRouteCapture;var _utils=require("@buoy-gg/shared-ui/utils");var _RouteObserver=require("./RouteObserver");var _routeEventStore=require("./stores/routeEventStore");var _navigationStackStore=require("./stores/navigationStackStore");var _browserRouteRegistry=require("./browserRouteRegistry");let leases=0;let stop;function startBrowserRouteCapture(){if(typeof window==="undefined")return()=>{};if(leases++===0){_routeEventStore.routeEventStore.hydrateBootCapture();let m;let c;let h="";const o=[];let r=-1;const
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.startBrowserRouteCapture=startBrowserRouteCapture;var _utils=require("@buoy-gg/shared-ui/utils");var _RouteObserver=require("./RouteObserver");var _routeEventStore=require("./stores/routeEventStore");var _navigationStackStore=require("./stores/navigationStackStore");var _browserRouteRegistry=require("./browserRouteRegistry");let leases=0;let stop;function startBrowserRouteCapture(){if(typeof window==="undefined")return()=>{};if(leases++===0){_routeEventStore.routeEventStore.hydrateBootCapture();let m;let c;let h="";const o=[];let r=-1;const w=()=>{const e=window.history.state;if(!e||typeof e!=="object")return void 0;const t=e.key??e.__TSR_key;return typeof t==="string"||typeof t==="number"?String(t):void 0};const g=e=>{for(let t=r-1;t>=0;t--)if(o[t].href===e)return t;for(let t=r+1;t<o.length;t++)if(o[t].href===e)return t;return-1};const v=e=>{const t=w();if(e.href===h&&e.kind==="pop"&&(t===void 0||o[r]?.key===t))return;if(e.kind==="replace"&&r>=0)o[r]={href:e.href,key:t};else if(e.kind==="pop"){const u=t===void 0?-1:o.findIndex(i=>i.key===t);const n=u>=0?u:g(e.href);if(n>=0)r=n;else{o.splice(r+1);o.push({href:e.href,key:t});r++}}else{o.splice(r+1);o.push({href:e.href,key:t});r++}h=e.href;const s=(0,_utils.getBrowserRouteURL)(e.href);const a=Date.now();const f=(0,_browserRouteRegistry.getBrowserRouteInfo)(s.pathname);if(!(0,_browserRouteRegistry.hasBrowserRouteEventSource)())_RouteObserver.routeObserver.emit({pathname:s.pathname,params:{...f.params,...Object.fromEntries(s.searchParams)},segments:f.segments,previousPathname:m,timestamp:a,timeSincePrevious:c===void 0?void 0:a-c});m=s.pathname;c=a;_navigationStackStore.navigationStackStore.setStack(o.slice(0,r+1).map(({href:u},n)=>{const i=(0,_utils.getBrowserRouteURL)(u);const p=(0,_browserRouteRegistry.getBrowserRouteInfo)(i.pathname);return{key:`browser:${n}`,name:p.segments.join("/")||"index",pathname:i.pathname,params:{...p.params,...Object.fromEntries(i.searchParams)},index:n,isFocused:n===r,canPop:n>0}}))};const l=e=>{if(!Number.isInteger(e)||e<0||e>=o.length)throw new Error("That browser history entry is unavailable.");window.history.go(e-r)};_navigationStackStore.navigationStackStore.setActions({navigateToIndex:l,popToIndex:l,goBack:_utils.browserRouter.back,popToTop:()=>l(0),navigateToRoute:(e,t)=>{const s={...t};const a=`/${e.replace(/^\//,"")}`.replace(/\[(\.\.\.)?([^\]]+)\]/g,(f,u,n)=>{if(!(n in s))return f;const i=s[n];delete s[n];return u&&Array.isArray(i)?i.map(p=>encodeURIComponent(String(p))).join("/"):encodeURIComponent(String(i))});_utils.browserRouter.push({pathname:a==="/index"?"/":a,params:s});return true}});stop=(0,_utils.subscribeBrowserNavigation)(v);v({href:(0,_utils.getBrowserHref)(),kind:"initial"})}let d=false;return()=>{if(d)return;d=true;if(--leases===0){stop?.();stop=void 0;_navigationStackStore.navigationStackStore.setActions(null)}}}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.NavigationStack=NavigationStack;var _react=require("react");var _reactNative=require("react-native");var _sharedUi=require("@buoy-gg/shared-ui");var _license=require("@buoy-gg/license");var _dataViewer=require("@buoy-gg/shared-ui/dataViewer");var _useNavigationStack=require("../useNavigationStack");var _testIDs=require("../utils/testIDs");var _jsxRuntime=require("react/jsx-runtime");function NavigationStack({style:
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.NavigationStack=NavigationStack;var _react=require("react");var _reactNative=require("react-native");var _sharedUi=require("@buoy-gg/shared-ui");var _license=require("@buoy-gg/license");var _dataViewer=require("@buoy-gg/shared-ui/dataViewer");var _useNavigationStack=require("../useNavigationStack");var _testIDs=require("../utils/testIDs");var _jsxRuntime=require("react/jsx-runtime");function NavigationStack({style:g,injectedStack:f,onAction:r,onCopyValueChange:b}){const c=(0,_useNavigationStack.useNavigationStack)();const y=f!=null;const F=(0,_sharedUi.useSafeAreaInsets)({minBottom:8});const t=y?f:c.stack;const S=y?true:c.isLoaded;const T=y?null:c.error;const k=(0,_react.useMemo)(()=>t.find(e=>e.isFocused)??null,[t]);const l=t.length;const p=l<=1;const w=e=>r?r("navigateToIndex",{index:e}):c.navigateToIndex(e);const B=e=>r?r("popToIndex",{index:e}):c.popToIndex(e);const D=()=>r?r("goBack"):c.goBack();const C=()=>r?r("popToTop"):c.popToTop();const[a,V]=(0,_react.useState)(null);const[m,d]=(0,_react.useState)(false);const u=(0,_license.useIsPro)();(0,_react.useEffect)(()=>{if(m&&u){d(false)}},[m,u]);const I=(0,_react.useMemo)(()=>{const e=t.map(n=>({pathname:n.pathname,name:n.name,params:n.params,isFocused:n.isFocused}));return JSON.stringify(e,null,2)},[t]);(0,_react.useEffect)(()=>{b?.(I)},[I,b]);const i=(0,_react.useMemo)(()=>{if(a!==null&&t[a]){return t[a]}return k},[a,t,k]);const z=(0,_react.useMemo)(()=>{return a!==null&&t[a]&&!t[a].isFocused},[a,t]);if(!S){return(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.container,g],children:(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.loadingContainer,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.loadingText,testID:"buoy-routes-stack-loading",children:"Loading navigation stack..."})})})}if(T){return(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.container,g],children:(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.errorContainer,testID:"buoy-routes-stack-error",children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.errorText,children:"Error loading stack"}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.errorDetail,testID:"buoy-routes-stack-error-detail",children:T.message})]})})}if(t.length===0){return(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.container,g],children:(0,_jsxRuntime.jsx)(_sharedUi.ToolEmptyState,{testID:"buoy-routes-stack-empty",otto:"walking",title:"No navigation stack",message:"Navigate to a route to see the stack"})})}const j=(e,n,o,x)=>{if(r){const h=globalThis.window?.confirm;if(!h||h(`${e}
|
|
2
2
|
|
|
3
|
-
${
|
|
3
|
+
${n}`)){x()}return}_reactNative.Alert.alert(e,n,[{text:"Cancel",style:"cancel"},{text:o,style:"destructive",onPress:x}])};const R=()=>{if(!u){d(true);return}if(p){_reactNative.Alert.alert("Cannot Go Back","Already at the root of the stack");return}D()};const N=()=>{if(!u){d(true);return}if(p){_reactNative.Alert.alert("Already at Top","Stack only has one screen");return}j("Pop to Top","This will remove all screens except the root screen.","Pop to Top",C)};const v=e=>{V(a===e?null:e)};const P=()=>{if(!u){d(true);return}if(!i)return;if(i.isFocused){_reactNative.Alert.alert("Already There","This route is already visible");return}w(i.index)};const $=()=>{if(!u){d(true);return}if(!i)return;if(i.isFocused){_reactNative.Alert.alert("Cannot Pop","Selected route is already visible");return}if(i.index===l-1){_reactNative.Alert.alert("Cannot Pop","No screens above selected route");return}const e=l-1-i.index;const n=i.index;j("Pop to Route",`Remove ${e} screen${e!==1?"s":""} above ${i.pathname}?`,"Pop",()=>B(n))};return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:[styles.container,g],children:[(0,_jsxRuntime.jsx)(_reactNative.ScrollView,{testID:"buoy-routes-stack-scroll",style:styles.stackScroll,contentContainerStyle:[styles.stackContent,{paddingBottom:styles.stackContent.padding+F.bottom}],children:[...t].reverse().map((e,n)=>{const o=t.length-1-n;const x=a===o;const h=Object.keys(e.params).length>0;const s=(0,_testIDs.stackItemTestID)(o);return(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.stackItemWrapper,testID:s,children:(0,_jsxRuntime.jsxs)(_reactNative.View,{style:[styles.stackItem,x&&styles.stackItemSelected],children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.stackItemHeader,children:[(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{style:styles.stackItemToggle,onPress:()=>v(o),activeOpacity:.7,testID:`${s}-toggle`,accessibilityRole:"button",accessibilityLabel:`${e.pathname}, ${e.isFocused?"focused":"mounted"}, position ${o} of ${l-1}`,children:[(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.expandIndicator,children:x?(0,_jsxRuntime.jsx)(_sharedUi.ChevronDown,{size:14,color:_sharedUi.night.color.textSecondary}):(0,_jsxRuntime.jsx)(_sharedUi.ChevronRight,{size:14,color:_sharedUi.night.color.textSecondary})}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.stackItemPath,numberOfLines:1,testID:`${s}-path`,children:e.pathname})]}),(0,_jsxRuntime.jsx)(_sharedUi.InlineCopyButton,{value:e.pathname,buttonStyle:styles.copyRouteButton,testID:`${s}-copy`}),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{onPress:()=>v(o),activeOpacity:.7,accessible:false,style:[styles.statusBadge,{backgroundColor:e.isFocused?`${_sharedUi.buoyColors.success}15`:"#3B82F615",borderColor:e.isFocused?`${_sharedUi.buoyColors.success}40`:"#3B82F640"}],children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.statusBadgeText,{color:e.isFocused?_sharedUi.buoyColors.success:"#3B82F6"}],testID:`${s}-status`,children:e.isFocused?"FOCUSED":"MOUNTED"})})]}),x&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.expandedContent,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.detailRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.detailLabel,children:"Route Name:"}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.detailValue,testID:`${s}-name`,children:e.name})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.detailRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.detailLabel,children:"Position:"}),(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.detailValue,testID:`${s}-position`,children:[o," / ",l-1]})]}),h&&(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.dataViewerContainer,children:(0,_jsxRuntime.jsx)(_dataViewer.DataViewer,{title:"Parameters",data:e.params,showTypeFilter:false})}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.actionsRow,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.actionWrapper,children:[(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:[styles.actionButton,p&&styles.actionButtonDisabled],onPress:R,disabled:p,testID:`${s}-back`,accessibilityRole:"button",accessibilityLabel:"Go back one screen",children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.actionButtonText,p&&styles.actionButtonTextDisabled],children:"Back"})}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.helpText,children:"Go back one screen"})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.actionWrapper,children:[(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:[styles.actionButton,e.isFocused&&styles.actionButtonDisabled],onPress:P,disabled:e.isFocused,testID:`${s}-go`,accessibilityRole:"button",accessibilityLabel:`Navigate to ${e.pathname}`,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.actionButtonText,e.isFocused&&styles.actionButtonTextDisabled],children:"Go"})}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.helpText,children:"Navigate to this route"})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.actionWrapper,children:[(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:[styles.actionButton,(e.isFocused||o===l-1)&&styles.actionButtonDisabled],onPress:$,disabled:e.isFocused||o===l-1,testID:`${s}-pop-to`,accessibilityRole:"button",accessibilityLabel:`Remove screens above ${e.pathname}`,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.actionButtonText,(e.isFocused||o===l-1)&&styles.actionButtonTextDisabled],children:"Pop To"})}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.helpText,children:"Remove screens above this"})]})]})]})]})},`stack-${o}-${e.key}`)})}),(0,_jsxRuntime.jsx)(_sharedUi.ProUpgradeModal,{visible:m,onClose:()=>d(false),featureName:"Stack Navigation"})]})}const styles=_reactNative.StyleSheet.create({container:{flex:1,backgroundColor:"transparent"},loadingContainer:{flex:1,justifyContent:"center",alignItems:"center",padding:32},loadingText:{color:_sharedUi.night.color.textSecondary,fontSize:14,fontFamily:_sharedUi.monoFont},errorContainer:{flex:1,justifyContent:"center",alignItems:"center",padding:32},errorText:{color:_sharedUi.buoyColors.error,fontSize:16,fontWeight:"600",fontFamily:_sharedUi.monoFont,marginBottom:8},errorDetail:{color:_sharedUi.night.color.textSecondary,fontSize:12,fontFamily:_sharedUi.monoFont,textAlign:"center"},emptyContainer:{flex:1,justifyContent:"center",alignItems:"center",padding:32},emptyText:{color:_sharedUi.night.color.text,fontSize:16,fontWeight:"600",fontFamily:_sharedUi.monoFont,marginBottom:8},emptySubtext:{color:_sharedUi.night.color.textSecondary,fontSize:14,fontFamily:_sharedUi.monoFont,textAlign:"center"},stackScroll:{flex:1},stackContent:{padding:8},stackItemWrapper:{marginBottom:6},stackItem:{backgroundColor:_sharedUi.night.color.surface,borderRadius:6,borderWidth:1,borderColor:_sharedUi.night.color.border,overflow:"hidden"},stackItemSelected:{borderColor:_sharedUi.night.color.accent,borderWidth:2},stackItemHeader:{flexDirection:"row",alignItems:"center",paddingVertical:10,paddingHorizontal:12,gap:8},stackItemToggle:{flex:1,flexDirection:"row",alignItems:"center",gap:8},expandIndicator:{width:20,alignItems:"center"},stackItemPath:{fontSize:13,fontWeight:"600",color:_sharedUi.night.color.text,fontFamily:_sharedUi.monoFont,flex:1},copyRouteButton:{padding:4,marginLeft:4},statusBadge:{borderRadius:4,paddingHorizontal:6,paddingVertical:2,borderWidth:1},statusBadgeText:{fontSize:10,fontWeight:"600",fontFamily:_sharedUi.monoFont},expandedContent:{paddingHorizontal:12,paddingTop:8,paddingBottom:12,borderTopWidth:1,borderTopColor:_sharedUi.night.color.border},detailRow:{marginBottom:8},detailLabel:{fontSize:10,color:_sharedUi.night.color.textSecondary,fontFamily:_sharedUi.monoFont,marginBottom:2},detailValue:{fontSize:12,color:_sharedUi.night.color.text,fontFamily:_sharedUi.monoFont},dataViewerContainer:{marginTop:4,marginHorizontal:-12,marginBottom:8},actionsRow:{flexDirection:"row",gap:6,marginTop:12},actionWrapper:{flex:1},actionButton:{backgroundColor:_sharedUi.night.color.surfaceElevated,paddingVertical:8,paddingHorizontal:8,borderRadius:6,alignItems:"center"},actionButtonDisabled:{opacity:.5},actionButtonText:{fontSize:12,fontWeight:"600",color:_sharedUi.night.color.text,fontFamily:_sharedUi.monoFont},actionButtonTextDisabled:{color:_sharedUi.night.color.textTertiary},helpText:{fontSize:9,color:_sharedUi.night.color.textSecondary,fontFamily:_sharedUi.monoFont,textAlign:"center",marginTop:4,lineHeight:12}});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.RouteEventExpandedContent=RouteEventExpandedContent;var _reactNative=require("react-native");var _sharedUi=require("@buoy-gg/shared-ui");var _dataViewer=require("@buoy-gg/shared-ui/dataViewer");var _jsxRuntime=require("react/jsx-runtime");function formatDuration(e){if(e<1e3){return`${e}ms`}if(e<6e4){return`${(e/1e3).toFixed(1)}s`}const t=Math.floor(e/6e4);const i=(e%6e4/1e3).toFixed(0);return`${t}m ${i}s`}function RouteEventExpandedContent({event:e,visitNumber:t,routeTemplate:i}){const
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.RouteEventExpandedContent=RouteEventExpandedContent;var _reactNative=require("react-native");var _sharedUi=require("@buoy-gg/shared-ui");var _dataViewer=require("@buoy-gg/shared-ui/dataViewer");var _jsxRuntime=require("react/jsx-runtime");function formatDuration(e){if(e<1e3){return`${e}ms`}if(e<6e4){return`${(e/1e3).toFixed(1)}s`}const t=Math.floor(e/6e4);const i=(e%6e4/1e3).toFixed(0);return`${t}m ${i}s`}function RouteEventExpandedContent({event:e,visitNumber:t,routeTemplate:i}){const l=e.params&&Object.keys(e.params).length>0;return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.container,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.section,children:[e.routeName&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.detailRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.detailLabel,children:"Name:"}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.detailValue,testID:"buoy-routes-detail-name",children:e.routeName})]}),e.matchedPath&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.detailRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.detailLabel,children:"Match:"}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.detailValue,testID:"buoy-routes-detail-match",children:e.matchedPath})]}),i&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.detailRow,testID:"buoy-routes-detail-template",children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.detailLabel,children:"Template:"}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.detailValue,testID:"buoy-routes-detail-template-value",children:i}),(0,_jsxRuntime.jsx)(_sharedUi.InlineCopyButton,{value:i,buttonStyle:styles.copyButton})]}),e.previousPathname&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.detailRow,testID:"buoy-routes-detail-from",children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.detailLabel,children:"From:"}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.detailValue,testID:"buoy-routes-detail-from-value",children:e.previousPathname}),(0,_jsxRuntime.jsx)(_sharedUi.InlineCopyButton,{value:e.previousPathname,buttonStyle:styles.copyButton})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.detailRow,testID:"buoy-routes-detail-to",children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.detailLabel,children:"To:"}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.detailValue,testID:"buoy-routes-detail-to-value",children:e.pathname}),(0,_jsxRuntime.jsx)(_sharedUi.InlineCopyButton,{value:e.pathname,buttonStyle:styles.copyButton})]})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.section,children:[e.timeSincePrevious!==void 0&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.detailRow,testID:"buoy-routes-detail-duration",children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.detailLabel,children:"Duration:"}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.detailValue,testID:"buoy-routes-detail-duration-value",children:formatDuration(e.timeSincePrevious)})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.detailRow,testID:"buoy-routes-detail-time",children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.detailLabel,children:"Time:"}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.detailValue,testID:"buoy-routes-detail-time-value",children:new Date(e.timestamp).toLocaleString()})]})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.section,children:[e.segments&&e.segments.length>0&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.detailRow,testID:"buoy-routes-detail-segments",children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.detailLabel,children:"Segments:"}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.detailValue,testID:"buoy-routes-detail-segments-value",children:e.segments.join(" \u2192 ")}),(0,_jsxRuntime.jsx)(_sharedUi.InlineCopyButton,{value:JSON.stringify(e.segments),buttonStyle:styles.copyButton})]}),l&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.dataViewerContainer,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.dataViewerHeader,children:[(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.dataViewerTitle,testID:"buoy-routes-detail-params-title",children:["Parameters (",Object.keys(e.params).length,")"]}),(0,_jsxRuntime.jsx)(_sharedUi.InlineCopyButton,{value:JSON.stringify(e.params,null,2),buttonStyle:styles.copyButton})]}),(0,_jsxRuntime.jsx)(_dataViewer.DataViewer,{data:e.params,title:"",showTypeFilter:true,rawMode:true,initialExpanded:true})]}),t>1&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.detailRow,testID:"buoy-routes-detail-visited",children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.detailLabel,children:"Visited:"}),(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.detailValue,testID:"buoy-routes-detail-visited-value",children:[t," time",t!==1?"s":""]})]})]})]})}const styles=_reactNative.StyleSheet.create({container:{gap:12},section:{gap:8},detailRow:{flexDirection:"row",alignItems:"center",gap:8},detailLabel:{fontSize:10,color:_sharedUi.night.color.textSecondary,fontFamily:_sharedUi.monoFont,fontWeight:"600",minWidth:70},detailValue:{fontSize:11,color:_sharedUi.night.color.text,fontFamily:_sharedUi.monoFont,flex:1},copyButton:{padding:4,borderRadius:4},dataViewerContainer:{marginTop:4},dataViewerHeader:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",marginBottom:8},dataViewerTitle:{fontSize:11,color:_sharedUi.night.color.textSecondary,fontFamily:_sharedUi.monoFont,fontWeight:"600"}});
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.RoutesSitemap=RoutesSitemap;var _react=require("react");var _sharedUi=require("@buoy-gg/shared-ui");var _reactNative=require("react-native");var _license=require("@buoy-gg/license");var _useRouteSitemap=require("../useRouteSitemap");var _testIDs=require("../utils/testIDs");var _jsxRuntime=require("react/jsx-runtime");const IS_DESKTOP=_reactNative.Platform.OS==="web"&&!(0,_license.isCapacitorNative)();const ACTION_ICON_SIZE=IS_DESKTOP?22:16;const HOME_ROUTE={path:"/",name:"index",type:"index",params:[],nodeType:"route",contextKey:"/",isInternal:false,children:[],depth:0};function RoutesSitemap({style:e,injectedRoutes:
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.RoutesSitemap=RoutesSitemap;var _react=require("react");var _sharedUi=require("@buoy-gg/shared-ui");var _reactNative=require("react-native");var _license=require("@buoy-gg/license");var _useRouteSitemap=require("../useRouteSitemap");var _testIDs=require("../utils/testIDs");var _jsxRuntime=require("react/jsx-runtime");const IS_DESKTOP=_reactNative.Platform.OS==="web"&&!(0,_license.isCapacitorNative)();const ACTION_ICON_SIZE=IS_DESKTOP?22:16;const HOME_ROUTE={path:"/",name:"index",type:"index",params:[],nodeType:"route",contextKey:"/",isInternal:false,children:[],depth:0};function RoutesSitemap({style:e,injectedRoutes:l,injectedSource:c,injectedLastUpdatedAt:u,onNavigateRoute:d}){const[n,p]=(0,_react.useState)("");const[x,s]=(0,_react.useState)(false);const[m,T]=(0,_react.useState)(new Set(["Static Routes","Dynamic Routes"]));const[h,f]=(0,_react.useState)(false);const[w,D]=(0,_react.useState)(false);const b=(0,_license.useIsPro)();(0,_react.useEffect)(()=>{if(w&&b){D(false)}},[w,b]);const y=(0,_sharedUi.useSafeRouter)();const{groups:j,stats:a,isLoaded:E,isSupported:O,filteredRoutes:I,routes:F,refresh:z,lastUpdatedAt:B,source:R}=(0,_useRouteSitemap.useRouteSitemap)({searchQuery:n,sortBy:"path",injectedRoutes:l,injectedSource:c,injectedLastUpdatedAt:u});const P=(0,_react.useMemo)(()=>{return{summary:{total:a.total,static:a.static,dynamic:a.dynamic,layouts:a.layouts,groups:a.groups,timestamp:new Date().toISOString()},groups:j.map(t=>({title:t.title,description:t.description,count:t.routes.length,routes:t.routes.map(o=>({path:o.path,name:o.name,type:o.type,params:o.params,depth:o.depth,hasChildren:o.children.length>0,childrenCount:o.children.length}))})),allRoutes:F.map(t=>t.path)}},[j,a,F]);const A=(0,_react.useCallback)(t=>{T(o=>{const i=new Set(o);if(i.has(t)){i.delete(t)}else{i.add(t)}return i})},[]);const C=(0,_react.useCallback)((t,o=0,i={})=>{const V=t.params;if(o>=V.length){let r=t.path;Object.entries(i).forEach(([g,H])=>{if(t.type==="catch-all"){r=r.replace(`[...${g}]`,H)}else{r=r.replace(`[${g}]`,H)}});try{y.push(r)}catch(g){_reactNative.Alert.alert("Navigation Error",String(g))}return}const S=V[o];const $=t.type==="catch-all"?`[...${S}]`:`[${S}]`;const L="Enter Parameter Value";const W=`Enter value for ${$}:
|
|
2
2
|
|
|
3
|
-
Route: ${t.path}`,[{text:"Cancel",style:"cancel"},{text:o<v.length-1?"Next":"Navigate",onPress:c=>{if(c&&c.trim()){const g={...i,[V]:c.trim()};B(t,o+1,g)}else{_reactNative.Alert.alert("Invalid Value","Please enter a value for the parameter")}}}],"plain-text")},[y]);const R=(0,_react.useCallback)((t,o)=>{if(d){d(t);return}if(!f&&!o?.bypassPro){T(true);return}if(t.type==="layout"||t.type==="group"){_reactNative.Alert.alert("Cannot Navigate",`${t.type==="layout"?"Layouts":"Route groups"} are not navigable routes`);return}if(t.type==="dynamic"||t.type==="catch-all"){if(t.params.length===0){try{y.push(t.path)}catch(i){_reactNative.Alert.alert("Navigation Error",String(i))}return}B(t);return}try{y.push(t.path)}catch(i){_reactNative.Alert.alert("Navigation Error",String(i))}},[y,B,f,d]);const P=(0,_react.useCallback)(()=>{R(HOME_ROUTE,{bypassPro:true})},[R]);const O=(0,_react.useCallback)(()=>{if(u)return;b(true);F();setTimeout(()=>b(false),400)},[u,F]);const A=(0,_react.useMemo)(()=>{if(!D)return"Awaiting route data";return`Updated ${(0,_sharedUi.formatRelativeTime)(D)}`},[D]);const N=(0,_react.useMemo)(()=>{if(!I)return"Source: unknown";return`Source: ${I}`},[I]);const z=(0,_react.useMemo)(()=>{if(r&&w.length>0){return[{title:"Search Results",icon:"",routes:w}]}return j},[r,w,j]);if(!W){return(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.container,e],children:(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.loadingContainer,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.loadingText,testID:"buoy-routes-sitemap-loading",children:$?"Loading routes...":"Route sitemap isn't available on the dashboard \u2014 the route tree lives on the device. Use the Events tab to see navigation here."})})})}return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:[styles.container,e],children:[x&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.searchContainer,testID:"buoy-routes-sitemap-search-field",children:[(0,_jsxRuntime.jsx)(_sharedUi.Search,{size:16,color:_sharedUi.night.color.textTertiary}),(0,_jsxRuntime.jsx)(_reactNative.TextInput,{style:styles.searchInput,placeholder:"Search routes...",placeholderTextColor:_sharedUi.night.color.placeholder,value:r,onChangeText:p,autoCapitalize:"none",autoCorrect:false,autoFocus:true,testID:"buoy-routes-sitemap-search",accessibilityLabel:"Search routes"}),r.length>0&&(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{onPress:()=>p(""),style:styles.clearButton,testID:"buoy-routes-sitemap-search-clear",accessibilityRole:"button",accessibilityLabel:"Clear route search",children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.clearButtonText,children:"\u2715"})}),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:styles.closeSearchButton,onPress:()=>{a(false);p("")},testID:"buoy-routes-sitemap-search-done",accessibilityRole:"button",accessibilityLabel:"Done searching routes",children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.closeSearchText,children:"Done"})})]}),(0,_jsxRuntime.jsxs)(_reactNative.ScrollView,{testID:"buoy-routes-sitemap-scroll",style:styles.scrollView,contentContainerStyle:styles.scrollContent,children:[!x&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.header,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.actionsRow,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:[styles.actionWrapper,IS_DESKTOP&&styles.actionWrapperDesktop],children:[(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:[styles.iconButton,IS_DESKTOP&&styles.iconButtonDesktop],onPress:P,accessibilityLabel:"Go to home route",accessibilityRole:"button",testID:"buoy-routes-sitemap-home",children:(0,_jsxRuntime.jsx)(_sharedUi.Home,{size:ACTION_ICON_SIZE,color:_sharedUi.night.color.textSecondary})}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.actionLabel,IS_DESKTOP&&styles.actionLabelDesktop],children:"Home"})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:[styles.actionWrapper,IS_DESKTOP&&styles.actionWrapperDesktop],children:[(0,_jsxRuntime.jsx)(_sharedUi.CopyButton,{value:H,testID:"buoy-routes-sitemap-copy",size:IS_DESKTOP?ACTION_ICON_SIZE:14,buttonStyle:IS_DESKTOP?styles.actionButtonHeaderDesktop:styles.actionButtonHeader}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.actionLabel,IS_DESKTOP&&styles.actionLabelDesktop],children:"Copy"})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:[styles.actionWrapper,IS_DESKTOP&&styles.actionWrapperDesktop],children:[(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:[styles.iconButton,IS_DESKTOP&&styles.iconButtonDesktop,u&&styles.refreshButtonDisabled],onPress:O,disabled:u,testID:"buoy-routes-sitemap-refresh",accessibilityRole:"button",accessibilityLabel:"Refresh route tree",children:(0,_jsxRuntime.jsx)(_sharedUi.RefreshCw,{size:ACTION_ICON_SIZE,color:u?_sharedUi.night.color.textTertiary:_sharedUi.night.color.textSecondary})}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.actionLabel,IS_DESKTOP&&styles.actionLabelDesktop],children:"Refresh"})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:[styles.actionWrapper,IS_DESKTOP&&styles.actionWrapperDesktop],children:[(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:[styles.iconButton,IS_DESKTOP&&styles.iconButtonDesktop],onPress:()=>a(true),testID:"buoy-routes-sitemap-search-open",accessibilityRole:"button",accessibilityLabel:"Search routes",children:(0,_jsxRuntime.jsx)(_sharedUi.Search,{size:ACTION_ICON_SIZE,color:_sharedUi.night.color.textSecondary})}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.actionLabel,IS_DESKTOP&&styles.actionLabelDesktop],children:"Search"})]})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.statsGrid,children:[(0,_jsxRuntime.jsx)(StatItem,{value:n.total,label:"Total",id:"total"}),(0,_jsxRuntime.jsx)(StatItem,{value:n.static,label:"Static",id:"static"}),(0,_jsxRuntime.jsx)(StatItem,{value:n.dynamic,label:"Dynamic",id:"dynamic"}),(0,_jsxRuntime.jsx)(StatItem,{value:n.catchAll,label:"Catch-All",id:"catch-all"}),(0,_jsxRuntime.jsx)(StatItem,{value:n.layouts,label:"Layouts",id:"layouts"}),(0,_jsxRuntime.jsx)(StatItem,{value:n.groups,label:"Groups",id:"groups"})]})]}),z.length===0?(0,_jsxRuntime.jsx)(_sharedUi.ToolEmptyState,{testID:"buoy-routes-sitemap-empty",otto:"map",title:"No routes found",message:"Nothing in the router matches. Clear the search to see the whole tree."}):z.map(t=>(0,_jsxRuntime.jsx)(RouteGroupView,{group:t,isExpanded:r.length>0||m.has(t.title),onToggleExpand:()=>E(t.title),onNavigate:R},t.title)),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.metaFooter,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.metaText,testID:"buoy-routes-sitemap-updated",children:A}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.sourceBadge,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.sourceText,testID:"buoy-routes-sitemap-source",children:N})})]})]}),(0,_jsxRuntime.jsx)(_sharedUi.ProUpgradeModal,{visible:S,onClose:()=>T(false),featureName:"Route Navigation"})]})}function StatItem({value:e,label:s,id:l}){return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.statItem,testID:`buoy-routes-stat-${l}`,accessibilityLabel:`${s}, ${e}`,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.statValue,testID:`buoy-routes-stat-${l}-value`,children:e}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.statLabel,children:s})]})}function RouteGroupView({group:e,isExpanded:s,onToggleExpand:l,onNavigate:h}){return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.groupContainer,children:[(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{style:styles.groupHeader,onPress:l,activeOpacity:.7,testID:(0,_testIDs.sitemapGroupTestID)(e.title),accessibilityRole:"button",accessibilityLabel:`${e.title}, ${e.routes.length} routes`,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.groupHeaderLeft,children:[s?(0,_jsxRuntime.jsx)(_sharedUi.ChevronDown,{size:14,color:_sharedUi.night.color.textSecondary}):(0,_jsxRuntime.jsx)(_sharedUi.ChevronRight,{size:14,color:_sharedUi.night.color.textSecondary}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.groupTitle,children:e.title})]}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.groupBadge,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.groupCount,testID:`${(0,_testIDs.sitemapGroupTestID)(e.title)}-count`,children:e.routes.length})})]}),e.description&&(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.groupDescription,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.groupDescriptionText,children:e.description})}),s&&(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.routesList,children:e.routes.map((d,r)=>(0,_jsxRuntime.jsx)(RouteItemView,{route:d,onNavigate:h},`${d.path}-${r}`))})]})}function RouteItemView({route:e,depth:s=0,onNavigate:l}){const[h,d]=(0,_react.useState)(false);const r=e.children.length>0;const p=getRouteTypeColor(e.type);const x=e.type!=="layout"&&e.type!=="group";const a=(0,_testIDs.sitemapRouteTestID)(e.path);const m=r;const C=m?h:true;return(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.routeItem,{marginLeft:s*12}],testID:a,children:(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.routeCard,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.routeHeader,children:[m?(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{style:styles.routeHeaderLeft,onPress:()=>d(!h),activeOpacity:.7,testID:`${a}-toggle`,accessibilityRole:"button",accessibilityLabel:`${e.path}, ${e.type}, ${e.children.length} nested`,children:[(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.expandIndicator,children:h?(0,_jsxRuntime.jsx)(_sharedUi.ChevronDown,{size:14,color:_sharedUi.night.color.textSecondary}):(0,_jsxRuntime.jsx)(_sharedUi.ChevronRight,{size:14,color:_sharedUi.night.color.textSecondary})}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.routePath,numberOfLines:3,testID:`${a}-path`,children:e.path})]}):(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.routeHeaderLeft,accessible:true,accessibilityLabel:`${e.path}, ${e.type}`,children:[(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.expandIndicator}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.routePath,numberOfLines:3,testID:`${a}-path`,children:e.path})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.routeHeaderActions,children:[r&&(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.childCountBadge,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.childCountText,testID:`${a}-children-count`,children:e.children.length})}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.typeTag,{backgroundColor:`${p}15`,borderColor:`${p}40`}],children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.typeText,{color:p}],testID:`${a}-type`,children:e.type.toUpperCase()})}),(0,_jsxRuntime.jsx)(_sharedUi.InlineCopyButton,{value:e.path,buttonStyle:styles.iconAction,testID:`${a}-copy`}),x&&(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:styles.goButton,onPress:()=>l(e),activeOpacity:.7,testID:`${a}-go`,accessibilityRole:"button",accessibilityLabel:`Go to ${e.path}`,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.goButtonText,children:"Go"})})]})]}),C&&r&&(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.childrenContainer,children:e.children.map((u,b)=>(0,_jsxRuntime.jsx)(RouteItemView,{route:u,depth:s+1,onNavigate:l},`${u.path}-${b}`))})]})})}function getRouteTypeColor(e){switch(e){case"static":return"#3B82F6";case"dynamic":return"#F59E0B";case"catch-all":return"#EC4899";case"index":return"#10B981";case"layout":return"#8B5CF6";case"group":return"#6366F1";case"not-found":return"#EF4444";default:return"#6B7280"}}const styles=_reactNative.StyleSheet.create({container:{flex:1,backgroundColor:"transparent"},loadingContainer:{flex:1,justifyContent:"center",alignItems:"center"},loadingText:{color:_sharedUi.night.color.textSecondary,fontSize:14,fontFamily:_sharedUi.monoFont,textAlign:"center",lineHeight:20,paddingHorizontal:32,maxWidth:420},header:{flexDirection:"column",padding:8,borderBottomWidth:1,borderBottomColor:_sharedUi.night.color.border,gap:12,marginBottom:8},actionsRow:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",gap:12,paddingBottom:4},statsGrid:{flexDirection:"row",flexWrap:"wrap",gap:8},statItem:{flexGrow:1,flexShrink:1,flexBasis:"30%",minWidth:90,backgroundColor:_sharedUi.night.color.surface,borderRadius:8,paddingVertical:10,paddingHorizontal:12,alignItems:"center"},statValue:{fontSize:18,fontWeight:"800",color:_sharedUi.night.color.text,fontFamily:_sharedUi.monoFont},statLabel:{fontSize:10,color:_sharedUi.night.color.textTertiary,marginTop:4,fontFamily:_sharedUi.monoFont,textTransform:"uppercase",letterSpacing:.5},actionWrapper:{flex:1,alignItems:"center",justifyContent:"center",gap:4,minWidth:48},actionWrapperDesktop:{gap:8,minWidth:72},actionButtonHeader:{padding:6,borderRadius:4,backgroundColor:_sharedUi.night.color.surfaceElevated},actionButtonHeaderDesktop:{padding:12,borderRadius:8,backgroundColor:_sharedUi.night.color.surfaceElevated},iconButton:{padding:6,borderRadius:4,alignItems:"center",justifyContent:"center"},iconButtonDesktop:{padding:12,borderRadius:8,backgroundColor:_sharedUi.night.color.surfaceElevated},actionLabel:{fontSize:8,color:_sharedUi.night.color.textTertiary,fontFamily:_sharedUi.monoFont,textTransform:"uppercase",letterSpacing:.5},actionLabelDesktop:{fontSize:12},refreshButtonDisabled:{opacity:.5},metaFooter:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",gap:8,paddingHorizontal:16,paddingVertical:16,marginTop:16,borderTopWidth:1,borderTopColor:_sharedUi.night.color.border},metaText:{fontSize:12,color:_sharedUi.night.color.textSecondary,fontFamily:_sharedUi.monoFont},sourceBadge:{paddingHorizontal:8,paddingVertical:2,borderRadius:999,borderWidth:1,borderColor:_sharedUi.night.color.border,backgroundColor:_sharedUi.night.color.surface},sourceText:{fontSize:11,color:_sharedUi.night.color.textSecondary,textTransform:"capitalize",fontFamily:_sharedUi.monoFont},searchContainer:{flexDirection:"row",alignItems:"center",padding:8,gap:8,borderBottomWidth:1,borderBottomColor:_sharedUi.night.color.border},searchInput:{flex:1,color:_sharedUi.night.color.text,fontSize:14,fontFamily:_sharedUi.monoFont},clearButton:{padding:4},clearButtonText:{color:_sharedUi.night.color.textTertiary,fontSize:18},closeSearchButton:{paddingHorizontal:8,paddingVertical:4},closeSearchText:{color:_sharedUi.night.color.accent,fontSize:14,fontWeight:"600",fontFamily:_sharedUi.monoFont},scrollView:{flex:1},scrollContent:{paddingBottom:8},emptyState:{padding:32,alignItems:"center"},emptyText:{color:_sharedUi.night.color.textSecondary,fontSize:14,fontFamily:_sharedUi.monoFont},groupContainer:{marginVertical:4},groupHeader:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",padding:12,paddingHorizontal:16,backgroundColor:_sharedUi.night.color.surface,borderLeftWidth:3,borderLeftColor:_sharedUi.night.color.fillTertiary},groupHeaderLeft:{flexDirection:"row",alignItems:"center",gap:8,flex:1},groupTitle:{fontSize:12,fontWeight:"700",color:_sharedUi.night.color.text,fontFamily:_sharedUi.monoFont,textTransform:"uppercase",letterSpacing:.8},groupBadge:{backgroundColor:"#3B82F615",borderColor:"#3B82F640",borderWidth:1,borderRadius:12,paddingHorizontal:8,paddingVertical:3,minWidth:24,alignItems:"center",justifyContent:"center"},groupCount:{fontSize:11,fontWeight:"600",color:"#3B82F6",fontFamily:_sharedUi.monoFont},routesList:{backgroundColor:"transparent"},groupDescription:{paddingHorizontal:16,paddingVertical:8,marginBottom:8,backgroundColor:_sharedUi.night.color.surfaceElevated,borderLeftWidth:3,borderLeftColor:_sharedUi.night.color.fillTertiary},groupDescriptionText:{fontSize:11,color:_sharedUi.night.color.textSecondary,fontFamily:_sharedUi.monoFont,lineHeight:16},routeItem:{marginBottom:6},routeCard:{backgroundColor:_sharedUi.night.color.surface,borderRadius:6,borderWidth:1,borderColor:_sharedUi.night.color.border,overflow:"hidden",shadowColor:"#000",shadowOffset:{width:0,height:1},shadowOpacity:.05,shadowRadius:2,elevation:1},routeHeader:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",paddingVertical:7,paddingHorizontal:10,gap:8},expandIndicator:{width:18,alignItems:"center"},routeHeaderLeft:{flexDirection:"row",alignItems:"center",gap:8,flex:1},routePath:{fontSize:13,fontWeight:"600",color:_sharedUi.night.color.text,fontFamily:_sharedUi.monoFont,flex:1},routeHeaderActions:{flexDirection:"row",alignItems:"center",gap:6},childCountBadge:{backgroundColor:"#6B728015",borderColor:"#6B728040",borderWidth:1,borderRadius:12,paddingHorizontal:7,paddingVertical:2,minWidth:22,alignItems:"center",justifyContent:"center"},childCountText:{fontSize:11,fontWeight:"600",color:_sharedUi.night.color.textSecondary,fontFamily:_sharedUi.monoFont},typeTag:{borderRadius:4,paddingHorizontal:6,paddingVertical:2,borderWidth:1},typeText:{fontSize:10,fontWeight:"600",fontFamily:_sharedUi.monoFont},iconAction:{width:28,height:24,borderRadius:4,backgroundColor:_sharedUi.night.color.surfaceElevated,borderWidth:1,borderColor:_sharedUi.night.color.border,alignItems:"center",justifyContent:"center"},goButton:{height:24,paddingHorizontal:10,borderRadius:4,alignItems:"center",justifyContent:"center",backgroundColor:_sharedUi.night.color.accentSoft,borderWidth:1,borderColor:_sharedUi.night.color.accentBorder},goButtonText:{fontSize:12,color:_sharedUi.night.color.accent,fontFamily:_sharedUi.monoFont,fontWeight:"600"},childrenContainer:{borderLeftWidth:2,borderLeftColor:_sharedUi.night.color.border,marginLeft:16,marginRight:8,marginTop:2,marginBottom:8}});
|
|
3
|
+
Route: ${t.path}`;const U=r=>{if(r&&r.trim()){C(t,o+1,{...i,[S]:r.trim()})}};if(typeof _reactNative.Alert.prompt!=="function"){const r=globalThis.prompt;if(r)U(r(`${L}
|
|
4
|
+
|
|
5
|
+
${W}`));else _reactNative.Alert.alert(L,`${t.path} needs a value for ${$}, and this platform can't ask for one here.`);return}_reactNative.Alert.prompt(L,W,[{text:"Cancel",style:"cancel"},{text:o<V.length-1?"Next":"Navigate",onPress:r=>{if(r&&r.trim()){const g={...i,[S]:r.trim()};C(t,o+1,g)}else{_reactNative.Alert.alert("Invalid Value","Please enter a value for the parameter")}}}],"plain-text")},[y]);const v=(0,_react.useCallback)((t,o)=>{if(d){d(t);return}if(!b&&!o?.bypassPro){D(true);return}if(t.type==="layout"||t.type==="group"){_reactNative.Alert.alert("Cannot Navigate",`${t.type==="layout"?"Layouts":"Route groups"} are not navigable routes`);return}if(t.type==="dynamic"||t.type==="catch-all"){if(t.params.length===0){try{y.push(t.path)}catch(i){_reactNative.Alert.alert("Navigation Error",String(i))}return}C(t);return}try{y.push(t.path)}catch(i){_reactNative.Alert.alert("Navigation Error",String(i))}},[y,C,b,d]);const N=(0,_react.useCallback)(()=>{v(HOME_ROUTE,{bypassPro:true})},[v]);const G=(0,_react.useCallback)(()=>{if(h)return;f(true);z();setTimeout(()=>f(false),400)},[h,z]);const _=(0,_react.useMemo)(()=>{if(!B)return"Awaiting route data";return`Updated ${(0,_sharedUi.formatRelativeTime)(B)}`},[B]);const M=(0,_react.useMemo)(()=>{if(!R)return"Source: unknown";return`Source: ${R}`},[R]);const k=(0,_react.useMemo)(()=>{if(n&&I.length>0){return[{title:"Search Results",icon:"",routes:I}]}return j},[n,I,j]);if(!E){return(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.container,e],children:(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.loadingContainer,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.loadingText,testID:"buoy-routes-sitemap-loading",children:O?"Loading routes...":"Route sitemap isn't available on the dashboard \u2014 the route tree lives on the device. Use the Events tab to see navigation here."})})})}return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:[styles.container,e],children:[x&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.searchContainer,testID:"buoy-routes-sitemap-search-field",children:[(0,_jsxRuntime.jsx)(_sharedUi.Search,{size:16,color:_sharedUi.night.color.textTertiary}),(0,_jsxRuntime.jsx)(_reactNative.TextInput,{style:styles.searchInput,placeholder:"Search routes...",placeholderTextColor:_sharedUi.night.color.placeholder,value:n,onChangeText:p,autoCapitalize:"none",autoCorrect:false,autoFocus:true,testID:"buoy-routes-sitemap-search",accessibilityLabel:"Search routes"}),n.length>0&&(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{onPress:()=>p(""),style:styles.clearButton,testID:"buoy-routes-sitemap-search-clear",accessibilityRole:"button",accessibilityLabel:"Clear route search",children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.clearButtonText,children:"\u2715"})}),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:styles.closeSearchButton,onPress:()=>{s(false);p("")},testID:"buoy-routes-sitemap-search-done",accessibilityRole:"button",accessibilityLabel:"Done searching routes",children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.closeSearchText,children:"Done"})})]}),(0,_jsxRuntime.jsxs)(_reactNative.ScrollView,{testID:"buoy-routes-sitemap-scroll",style:styles.scrollView,contentContainerStyle:styles.scrollContent,children:[!x&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.header,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.actionsRow,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:[styles.actionWrapper,IS_DESKTOP&&styles.actionWrapperDesktop],children:[(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:[styles.iconButton,IS_DESKTOP&&styles.iconButtonDesktop],onPress:N,accessibilityLabel:"Go to home route",accessibilityRole:"button",testID:"buoy-routes-sitemap-home",children:(0,_jsxRuntime.jsx)(_sharedUi.Home,{size:ACTION_ICON_SIZE,color:_sharedUi.night.color.textSecondary})}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.actionLabel,IS_DESKTOP&&styles.actionLabelDesktop],children:"Home"})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:[styles.actionWrapper,IS_DESKTOP&&styles.actionWrapperDesktop],children:[(0,_jsxRuntime.jsx)(_sharedUi.CopyButton,{value:P,testID:"buoy-routes-sitemap-copy",size:IS_DESKTOP?ACTION_ICON_SIZE:14,buttonStyle:IS_DESKTOP?styles.actionButtonHeaderDesktop:styles.actionButtonHeader}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.actionLabel,IS_DESKTOP&&styles.actionLabelDesktop],children:"Copy"})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:[styles.actionWrapper,IS_DESKTOP&&styles.actionWrapperDesktop],children:[(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:[styles.iconButton,IS_DESKTOP&&styles.iconButtonDesktop,h&&styles.refreshButtonDisabled],onPress:G,disabled:h,testID:"buoy-routes-sitemap-refresh",accessibilityRole:"button",accessibilityLabel:"Refresh route tree",children:(0,_jsxRuntime.jsx)(_sharedUi.RefreshCw,{size:ACTION_ICON_SIZE,color:h?_sharedUi.night.color.textTertiary:_sharedUi.night.color.textSecondary})}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.actionLabel,IS_DESKTOP&&styles.actionLabelDesktop],children:"Refresh"})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:[styles.actionWrapper,IS_DESKTOP&&styles.actionWrapperDesktop],children:[(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:[styles.iconButton,IS_DESKTOP&&styles.iconButtonDesktop],onPress:()=>s(true),testID:"buoy-routes-sitemap-search-open",accessibilityRole:"button",accessibilityLabel:"Search routes",children:(0,_jsxRuntime.jsx)(_sharedUi.Search,{size:ACTION_ICON_SIZE,color:_sharedUi.night.color.textSecondary})}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.actionLabel,IS_DESKTOP&&styles.actionLabelDesktop],children:"Search"})]})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.statsGrid,children:[(0,_jsxRuntime.jsx)(StatItem,{value:a.total,label:"Total",id:"total"}),(0,_jsxRuntime.jsx)(StatItem,{value:a.static,label:"Static",id:"static"}),(0,_jsxRuntime.jsx)(StatItem,{value:a.dynamic,label:"Dynamic",id:"dynamic"}),(0,_jsxRuntime.jsx)(StatItem,{value:a.catchAll,label:"Catch-All",id:"catch-all"}),(0,_jsxRuntime.jsx)(StatItem,{value:a.layouts,label:"Layouts",id:"layouts"}),(0,_jsxRuntime.jsx)(StatItem,{value:a.groups,label:"Groups",id:"groups"})]})]}),k.length===0?(0,_jsxRuntime.jsx)(_sharedUi.ToolEmptyState,{testID:"buoy-routes-sitemap-empty",otto:"map",title:"No routes found",message:"Nothing in the router matches. Clear the search to see the whole tree."}):k.map(t=>(0,_jsxRuntime.jsx)(RouteGroupView,{group:t,isExpanded:n.length>0||m.has(t.title),onToggleExpand:()=>A(t.title),onNavigate:v},t.title)),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.metaFooter,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.metaText,testID:"buoy-routes-sitemap-updated",children:_}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.sourceBadge,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.sourceText,testID:"buoy-routes-sitemap-source",children:M})})]})]}),(0,_jsxRuntime.jsx)(_sharedUi.ProUpgradeModal,{visible:w,onClose:()=>D(false),featureName:"Route Navigation"})]})}function StatItem({value:e,label:l,id:c}){return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.statItem,testID:`buoy-routes-stat-${c}`,accessibilityLabel:`${l}, ${e}`,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.statValue,testID:`buoy-routes-stat-${c}-value`,children:e}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.statLabel,children:l})]})}function RouteGroupView({group:e,isExpanded:l,onToggleExpand:c,onNavigate:u}){return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.groupContainer,children:[(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{style:styles.groupHeader,onPress:c,activeOpacity:.7,testID:(0,_testIDs.sitemapGroupTestID)(e.title),accessibilityRole:"button",accessibilityLabel:`${e.title}, ${e.routes.length} routes`,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.groupHeaderLeft,children:[l?(0,_jsxRuntime.jsx)(_sharedUi.ChevronDown,{size:14,color:_sharedUi.night.color.textSecondary}):(0,_jsxRuntime.jsx)(_sharedUi.ChevronRight,{size:14,color:_sharedUi.night.color.textSecondary}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.groupTitle,children:e.title})]}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.groupBadge,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.groupCount,testID:`${(0,_testIDs.sitemapGroupTestID)(e.title)}-count`,children:e.routes.length})})]}),e.description&&(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.groupDescription,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.groupDescriptionText,children:e.description})}),l&&(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.routesList,children:e.routes.map((d,n)=>(0,_jsxRuntime.jsx)(RouteItemView,{route:d,onNavigate:u},`${d.path}-${n}`))})]})}function RouteItemView({route:e,depth:l=0,onNavigate:c}){const[u,d]=(0,_react.useState)(false);const n=e.children.length>0;const p=getRouteTypeColor(e.type);const x=e.type!=="layout"&&e.type!=="group";const s=(0,_testIDs.sitemapRouteTestID)(e.path);const m=n;const T=m?u:true;return(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.routeItem,{marginLeft:l*12}],testID:s,children:(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.routeCard,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.routeHeader,children:[m?(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{style:styles.routeHeaderLeft,onPress:()=>d(!u),activeOpacity:.7,testID:`${s}-toggle`,accessibilityRole:"button",accessibilityLabel:`${e.path}, ${e.type}, ${e.children.length} nested`,children:[(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.expandIndicator,children:u?(0,_jsxRuntime.jsx)(_sharedUi.ChevronDown,{size:14,color:_sharedUi.night.color.textSecondary}):(0,_jsxRuntime.jsx)(_sharedUi.ChevronRight,{size:14,color:_sharedUi.night.color.textSecondary})}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.routePath,numberOfLines:3,testID:`${s}-path`,children:e.path})]}):(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.routeHeaderLeft,accessible:true,accessibilityLabel:`${e.path}, ${e.type}`,children:[(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.expandIndicator}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.routePath,numberOfLines:3,testID:`${s}-path`,children:e.path})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.routeHeaderActions,children:[n&&(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.childCountBadge,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.childCountText,testID:`${s}-children-count`,children:e.children.length})}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.typeTag,{backgroundColor:`${p}15`,borderColor:`${p}40`}],children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.typeText,{color:p}],testID:`${s}-type`,children:e.type.toUpperCase()})}),(0,_jsxRuntime.jsx)(_sharedUi.InlineCopyButton,{value:e.path,buttonStyle:styles.iconAction,testID:`${s}-copy`}),x&&(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:styles.goButton,onPress:()=>c(e),activeOpacity:.7,testID:`${s}-go`,accessibilityRole:"button",accessibilityLabel:`Go to ${e.path}`,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.goButtonText,children:"Go"})})]})]}),T&&n&&(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.childrenContainer,children:e.children.map((h,f)=>(0,_jsxRuntime.jsx)(RouteItemView,{route:h,depth:l+1,onNavigate:c},`${h.path}-${f}`))})]})})}function getRouteTypeColor(e){switch(e){case"static":return"#3B82F6";case"dynamic":return"#F59E0B";case"catch-all":return"#EC4899";case"index":return"#10B981";case"layout":return"#8B5CF6";case"group":return"#6366F1";case"not-found":return"#EF4444";default:return"#6B7280"}}const styles=_reactNative.StyleSheet.create({container:{flex:1,backgroundColor:"transparent"},loadingContainer:{flex:1,justifyContent:"center",alignItems:"center"},loadingText:{color:_sharedUi.night.color.textSecondary,fontSize:14,fontFamily:_sharedUi.monoFont,textAlign:"center",lineHeight:20,paddingHorizontal:32,maxWidth:420},header:{flexDirection:"column",padding:8,borderBottomWidth:1,borderBottomColor:_sharedUi.night.color.border,gap:12,marginBottom:8},actionsRow:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",gap:12,paddingBottom:4},statsGrid:{flexDirection:"row",flexWrap:"wrap",gap:8},statItem:{flexGrow:1,flexShrink:1,flexBasis:"30%",minWidth:90,backgroundColor:_sharedUi.night.color.surface,borderRadius:8,paddingVertical:10,paddingHorizontal:12,alignItems:"center"},statValue:{fontSize:18,fontWeight:"800",color:_sharedUi.night.color.text,fontFamily:_sharedUi.monoFont},statLabel:{fontSize:10,color:_sharedUi.night.color.textTertiary,marginTop:4,fontFamily:_sharedUi.monoFont,textTransform:"uppercase",letterSpacing:.5},actionWrapper:{flex:1,alignItems:"center",justifyContent:"center",gap:4,minWidth:48},actionWrapperDesktop:{gap:8,minWidth:72},actionButtonHeader:{padding:6,borderRadius:4,backgroundColor:_sharedUi.night.color.surfaceElevated},actionButtonHeaderDesktop:{padding:12,borderRadius:8,backgroundColor:_sharedUi.night.color.surfaceElevated},iconButton:{padding:6,borderRadius:4,alignItems:"center",justifyContent:"center"},iconButtonDesktop:{padding:12,borderRadius:8,backgroundColor:_sharedUi.night.color.surfaceElevated},actionLabel:{fontSize:8,color:_sharedUi.night.color.textTertiary,fontFamily:_sharedUi.monoFont,textTransform:"uppercase",letterSpacing:.5},actionLabelDesktop:{fontSize:12},refreshButtonDisabled:{opacity:.5},metaFooter:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",gap:8,paddingHorizontal:16,paddingVertical:16,marginTop:16,borderTopWidth:1,borderTopColor:_sharedUi.night.color.border},metaText:{fontSize:12,color:_sharedUi.night.color.textSecondary,fontFamily:_sharedUi.monoFont},sourceBadge:{paddingHorizontal:8,paddingVertical:2,borderRadius:999,borderWidth:1,borderColor:_sharedUi.night.color.border,backgroundColor:_sharedUi.night.color.surface},sourceText:{fontSize:11,color:_sharedUi.night.color.textSecondary,textTransform:"capitalize",fontFamily:_sharedUi.monoFont},searchContainer:{flexDirection:"row",alignItems:"center",padding:8,gap:8,borderBottomWidth:1,borderBottomColor:_sharedUi.night.color.border},searchInput:{flex:1,color:_sharedUi.night.color.text,fontSize:14,fontFamily:_sharedUi.monoFont},clearButton:{padding:4},clearButtonText:{color:_sharedUi.night.color.textTertiary,fontSize:18},closeSearchButton:{paddingHorizontal:8,paddingVertical:4},closeSearchText:{color:_sharedUi.night.color.accent,fontSize:14,fontWeight:"600",fontFamily:_sharedUi.monoFont},scrollView:{flex:1},scrollContent:{paddingBottom:8},emptyState:{padding:32,alignItems:"center"},emptyText:{color:_sharedUi.night.color.textSecondary,fontSize:14,fontFamily:_sharedUi.monoFont},groupContainer:{marginVertical:4},groupHeader:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",padding:12,paddingHorizontal:16,backgroundColor:_sharedUi.night.color.surface,borderLeftWidth:3,borderLeftColor:_sharedUi.night.color.fillTertiary},groupHeaderLeft:{flexDirection:"row",alignItems:"center",gap:8,flex:1},groupTitle:{fontSize:12,fontWeight:"700",color:_sharedUi.night.color.text,fontFamily:_sharedUi.monoFont,textTransform:"uppercase",letterSpacing:.8},groupBadge:{backgroundColor:"#3B82F615",borderColor:"#3B82F640",borderWidth:1,borderRadius:12,paddingHorizontal:8,paddingVertical:3,minWidth:24,alignItems:"center",justifyContent:"center"},groupCount:{fontSize:11,fontWeight:"600",color:"#3B82F6",fontFamily:_sharedUi.monoFont},routesList:{backgroundColor:"transparent"},groupDescription:{paddingHorizontal:16,paddingVertical:8,marginBottom:8,backgroundColor:_sharedUi.night.color.surfaceElevated,borderLeftWidth:3,borderLeftColor:_sharedUi.night.color.fillTertiary},groupDescriptionText:{fontSize:11,color:_sharedUi.night.color.textSecondary,fontFamily:_sharedUi.monoFont,lineHeight:16},routeItem:{marginBottom:6},routeCard:{backgroundColor:_sharedUi.night.color.surface,borderRadius:6,borderWidth:1,borderColor:_sharedUi.night.color.border,overflow:"hidden",shadowColor:"#000",shadowOffset:{width:0,height:1},shadowOpacity:.05,shadowRadius:2,elevation:1},routeHeader:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",paddingVertical:7,paddingHorizontal:10,gap:8},expandIndicator:{width:18,alignItems:"center"},routeHeaderLeft:{flexDirection:"row",alignItems:"center",gap:8,flex:1},routePath:{fontSize:13,fontWeight:"600",color:_sharedUi.night.color.text,fontFamily:_sharedUi.monoFont,flex:1},routeHeaderActions:{flexDirection:"row",alignItems:"center",gap:6},childCountBadge:{backgroundColor:"#6B728015",borderColor:"#6B728040",borderWidth:1,borderRadius:12,paddingHorizontal:7,paddingVertical:2,minWidth:22,alignItems:"center",justifyContent:"center"},childCountText:{fontSize:11,fontWeight:"600",color:_sharedUi.night.color.textSecondary,fontFamily:_sharedUi.monoFont},typeTag:{borderRadius:4,paddingHorizontal:6,paddingVertical:2,borderWidth:1},typeText:{fontSize:10,fontWeight:"600",fontFamily:_sharedUi.monoFont},iconAction:{width:28,height:24,borderRadius:4,backgroundColor:_sharedUi.night.color.surfaceElevated,borderWidth:1,borderColor:_sharedUi.night.color.border,alignItems:"center",justifyContent:"center"},goButton:{height:24,paddingHorizontal:10,borderRadius:4,alignItems:"center",justifyContent:"center",backgroundColor:_sharedUi.night.color.accentSoft,borderWidth:1,borderColor:_sharedUi.night.color.accentBorder},goButtonText:{fontSize:12,color:_sharedUi.night.color.accent,fontFamily:_sharedUi.monoFont,fontWeight:"600"},childrenContainer:{borderLeftWidth:2,borderLeftColor:_sharedUi.night.color.border,marginLeft:16,marginRight:8,marginTop:2,marginBottom:8}});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.getExpoRouterStore=getExpoRouterStore;exports.getRouteNodeMetadata=getRouteNodeMetadata;exports.isExpoRouterStoreSupported=isExpoRouterStoreSupported;exports.isRouteListComplete=isRouteListComplete;exports.loadRouteNode=loadRouteNode;let cachedStore=null;let cachedStoreSource=null;let importError=null;let hasLoggedMissingStore=false;let hasLoggedMissingRouteNode=false;let lastRouteNodeTimestamp=null;function logOnce(e,o){if(__DEV__){if(o){console.error(
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.getExpoRouterStore=getExpoRouterStore;exports.getRouteNodeMetadata=getRouteNodeMetadata;exports.isExpoRouterStoreSupported=isExpoRouterStoreSupported;exports.isRouteListComplete=isRouteListComplete;exports.loadRouteNode=loadRouteNode;let cachedStore=null;let cachedStoreSource=null;let importError=null;let hasLoggedMissingStore=false;let hasLoggedMissingRouteNode=false;let lastRouteNodeTimestamp=null;function logOnce(e,o){if(__DEV__){if(o){console.error("[Buoy]",`[RouteEvents] ${e}`,o)}else{console.warn("[Buoy]",`[RouteEvents] ${e}`)}}}function isExpoRouterStoreSupported(){return typeof require!=="undefined"}function getExpoRouterStore(){if(cachedStore){return cachedStore}if(!isExpoRouterStoreSupported()){return null}const e=()=>{try{const t=require("expo-router/build/global-state/router-store");if(t?.store){cachedStore=t.store;cachedStoreSource="build";importError=null;hasLoggedMissingStore=false;return true}}catch(t){importError=t}return false};const o=()=>{try{const t=require("expo-router/src/global-state/router-store");if(t?.store){cachedStore=t.store;cachedStoreSource="src";importError=null;hasLoggedMissingStore=false;return true}}catch(t){importError=t}return false};if(e()||o()){return cachedStore}if(!hasLoggedMissingStore){logOnce("Unable to load expo-router internals. @buoy-gg/route-events requires expo-router >= 2.0.0. Install expo-router and ensure it is configured before using the Routes tab.",importError??void 0);hasLoggedMissingStore=true}return null}function loadRouteNode(){const e=getExpoRouterStore();if(!e){return null}if(e.routeNode){hasLoggedMissingRouteNode=false;lastRouteNodeTimestamp=Date.now();return e.routeNode}const o=e.navigationRef?.isReady?.();if(__DEV__&&!hasLoggedMissingRouteNode&&o){logOnce("Expo Router route tree is unavailable. Ensure your app directory is configured and that expo-router is initialized before opening the Route Events devtool.");hasLoggedMissingRouteNode=true}return null}function getRouteNodeMetadata(){return{source:cachedStoreSource,lastLoadedAt:lastRouteNodeTimestamp}}function isRouteListComplete(){return true}
|
package/lib/commonjs/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:true});Object.defineProperty(exports,"NavigationStack",{enumerable:true,get:function(){return _NavigationStack.NavigationStack}});Object.defineProperty(exports,"RouteEventDetail",{enumerable:true,get:function(){return _RouteEventDetail.RouteEventDetail}});Object.defineProperty(exports,"RouteEventExpandedContent",{enumerable:true,get:function(){return _RouteEventExpandedContent.RouteEventExpandedContent}});Object.defineProperty(exports,"RouteEventItemCompact",{enumerable:true,get:function(){return _RouteEventItemCompact.RouteEventItemCompact}});Object.defineProperty(exports,"RouteEventsModalWithTabs",{enumerable:true,get:function(){return _RouteEventsModalWithTabs.RouteEventsModalWithTabs}});Object.defineProperty(exports,"RouteObserver",{enumerable:true,get:function(){return _RouteObserver.RouteObserver}});Object.defineProperty(exports,"RouteParser",{enumerable:true,get:function(){return _RouteParser.RouteParser}});Object.defineProperty(exports,"RouteTracker",{enumerable:true,get:function(){return _RouteTracker.RouteTracker}});Object.defineProperty(exports,"RoutesSitemap",{enumerable:true,get:function(){return _RoutesSitemap.RoutesSitemap}});Object.defineProperty(exports,"RoutesToolView",{enumerable:true,get:function(){return _RouteEventsModalWithTabs.RoutesToolView}});Object.defineProperty(exports,"createRouteEventsTool",{enumerable:true,get:function(){return _preset.createRouteEventsTool}});Object.defineProperty(exports,"navigationStackStore",{enumerable:true,get:function(){return _navigationStackStore.navigationStackStore}});Object.defineProperty(exports,"registerBrowserRoutes",{enumerable:true,get:function(){return _browserRouteRegistry.registerBrowserRoutes}});Object.defineProperty(exports,"routeEventStore",{enumerable:true,get:function(){return _routeEventStore.routeEventStore}});Object.defineProperty(exports,"routeEventsSyncAdapter",{enumerable:true,get:function(){return _routeEventsSyncAdapter.routeEventsSyncAdapter}});Object.defineProperty(exports,"routeEventsToolPreset",{enumerable:true,get:function(){return _preset.routeEventsToolPreset}});Object.defineProperty(exports,"routeObserver",{enumerable:true,get:function(){return _RouteObserver.routeObserver}});Object.defineProperty(exports,"useNavigationStack",{enumerable:true,get:function(){return _useNavigationStack.useNavigationStack}});Object.defineProperty(exports,"useParentRoutes",{enumerable:true,get:function(){return _useRouteSitemap.useParentRoutes}});Object.defineProperty(exports,"useRoute",{enumerable:true,get:function(){return _useRouteSitemap.useRoute}});Object.defineProperty(exports,"useRouteEvents",{enumerable:true,get:function(){return _useRouteEvents.useRouteEvents}});Object.defineProperty(exports,"useRouteObserver",{enumerable:true,get:function(){return _useRouteObserver.useRouteObserver}});Object.defineProperty(exports,"useRouteObserverReactNavigation",{enumerable:true,get:function(){return _useRouteObserverReactNavigation.useRouteObserverReactNavigation}});Object.defineProperty(exports,"useRouteSitemap",{enumerable:true,get:function(){return _useRouteSitemap.useRouteSitemap}});var _preset=require("./preset");var _RouteEventsModalWithTabs=require("./components/RouteEventsModalWithTabs");var _RouteTracker=require("./RouteTracker");var _browserRouteRegistry=require("./browserRouteRegistry");var _RoutesSitemap=require("./components/RoutesSitemap");var _NavigationStack=require("./components/NavigationStack");var _RouteEventItemCompact=require("./components/RouteEventItemCompact");var _RouteEventExpandedContent=require("./components/RouteEventExpandedContent");var _RouteEventDetail=require("./components/RouteEventDetail");var _useRouteObserver=require("./useRouteObserver");var _useRouteObserverReactNavigation=require("./useRouteObserverReactNavigation");var _useRouteEvents=require("./hooks/useRouteEvents");var _useRouteSitemap=require("./useRouteSitemap");var _useNavigationStack=require("./useNavigationStack");var _routeEventsSyncAdapter=require("./sync/routeEventsSyncAdapter");var _RouteParser=require("./RouteParser");var _RouteObserver=require("./RouteObserver");var _routeEventStore=require("./stores/routeEventStore");var _navigationStackStore=require("./stores/navigationStackStore");
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});Object.defineProperty(exports,"NavigationStack",{enumerable:true,get:function(){return _NavigationStack.NavigationStack}});Object.defineProperty(exports,"RouteEventDetail",{enumerable:true,get:function(){return _RouteEventDetail.RouteEventDetail}});Object.defineProperty(exports,"RouteEventExpandedContent",{enumerable:true,get:function(){return _RouteEventExpandedContent.RouteEventExpandedContent}});Object.defineProperty(exports,"RouteEventItemCompact",{enumerable:true,get:function(){return _RouteEventItemCompact.RouteEventItemCompact}});Object.defineProperty(exports,"RouteEventsModalWithTabs",{enumerable:true,get:function(){return _RouteEventsModalWithTabs.RouteEventsModalWithTabs}});Object.defineProperty(exports,"RouteObserver",{enumerable:true,get:function(){return _RouteObserver.RouteObserver}});Object.defineProperty(exports,"RouteParser",{enumerable:true,get:function(){return _RouteParser.RouteParser}});Object.defineProperty(exports,"RouteTracker",{enumerable:true,get:function(){return _RouteTracker.RouteTracker}});Object.defineProperty(exports,"RoutesSitemap",{enumerable:true,get:function(){return _RoutesSitemap.RoutesSitemap}});Object.defineProperty(exports,"RoutesToolView",{enumerable:true,get:function(){return _RouteEventsModalWithTabs.RoutesToolView}});Object.defineProperty(exports,"claimBrowserRouteEvents",{enumerable:true,get:function(){return _browserRouteRegistry.claimBrowserRouteEvents}});Object.defineProperty(exports,"createRouteEventsTool",{enumerable:true,get:function(){return _preset.createRouteEventsTool}});Object.defineProperty(exports,"navigationStackStore",{enumerable:true,get:function(){return _navigationStackStore.navigationStackStore}});Object.defineProperty(exports,"registerBrowserRoutes",{enumerable:true,get:function(){return _browserRouteRegistry.registerBrowserRoutes}});Object.defineProperty(exports,"routeEventStore",{enumerable:true,get:function(){return _routeEventStore.routeEventStore}});Object.defineProperty(exports,"routeEventsSyncAdapter",{enumerable:true,get:function(){return _routeEventsSyncAdapter.routeEventsSyncAdapter}});Object.defineProperty(exports,"routeEventsToolPreset",{enumerable:true,get:function(){return _preset.routeEventsToolPreset}});Object.defineProperty(exports,"routeObserver",{enumerable:true,get:function(){return _RouteObserver.routeObserver}});Object.defineProperty(exports,"useNavigationStack",{enumerable:true,get:function(){return _useNavigationStack.useNavigationStack}});Object.defineProperty(exports,"useParentRoutes",{enumerable:true,get:function(){return _useRouteSitemap.useParentRoutes}});Object.defineProperty(exports,"useRoute",{enumerable:true,get:function(){return _useRouteSitemap.useRoute}});Object.defineProperty(exports,"useRouteEvents",{enumerable:true,get:function(){return _useRouteEvents.useRouteEvents}});Object.defineProperty(exports,"useRouteObserver",{enumerable:true,get:function(){return _useRouteObserver.useRouteObserver}});Object.defineProperty(exports,"useRouteObserverReactNavigation",{enumerable:true,get:function(){return _useRouteObserverReactNavigation.useRouteObserverReactNavigation}});Object.defineProperty(exports,"useRouteSitemap",{enumerable:true,get:function(){return _useRouteSitemap.useRouteSitemap}});var _preset=require("./preset");var _RouteEventsModalWithTabs=require("./components/RouteEventsModalWithTabs");var _RouteTracker=require("./RouteTracker");var _browserRouteRegistry=require("./browserRouteRegistry");var _RoutesSitemap=require("./components/RoutesSitemap");var _NavigationStack=require("./components/NavigationStack");var _RouteEventItemCompact=require("./components/RouteEventItemCompact");var _RouteEventExpandedContent=require("./components/RouteEventExpandedContent");var _RouteEventDetail=require("./components/RouteEventDetail");var _useRouteObserver=require("./useRouteObserver");var _useRouteObserverReactNavigation=require("./useRouteObserverReactNavigation");var _useRouteEvents=require("./hooks/useRouteEvents");var _useRouteSitemap=require("./useRouteSitemap");var _useNavigationStack=require("./useNavigationStack");var _routeEventsSyncAdapter=require("./sync/routeEventsSyncAdapter");var _RouteParser=require("./RouteParser");var _RouteObserver=require("./RouteObserver");var _routeEventStore=require("./stores/routeEventStore");var _navigationStackStore=require("./stores/navigationStackStore");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.buildStack=buildStack;exports.useNavigationStack=useNavigationStack;var _react=require("react");var _safeReactNavigation=require("./utils/safeReactNavigation");var _sharedUi=require("@buoy-gg/shared-ui");const CommonActions=(0,_safeReactNavigation.getCommonActions)();const StackActions=(0,_safeReactNavigation.getStackActions)();function findScreenPath(t,e){if(!t||!t.routes)return null;for(const
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.buildStack=buildStack;exports.useNavigationStack=useNavigationStack;var _react=require("react");var _safeReactNavigation=require("./utils/safeReactNavigation");var _sharedUi=require("@buoy-gg/shared-ui");const CommonActions=(0,_safeReactNavigation.getCommonActions)();const StackActions=(0,_safeReactNavigation.getStackActions)();function findScreenPath(t,e){if(!t||!t.routes)return null;for(const n of t.routes){if(n.name===e){return[n.name]}if(n.state){const f=findScreenPath(n.state,e);if(f){return[n.name,...f]}}}return null}function buildNestedNavigateAction(t){if(t.length===0)return null;if(t.length===1){return CommonActions.navigate({name:t[0]})}let e={screen:t[t.length-1]};for(let n=t.length-2;n>=1;n--){e={screen:t[n],params:e}}return CommonActions.navigate({name:t[0],params:e})}function collectRoutesFromState(t,e=0,n="",f=true){if(!t||!Array.isArray(t.routes)||t.routes.length===0){return[]}const p=[];const d=typeof t.index==="number"?t.index:NaN;const R=Number.isInteger(d)&&d>=0&&d<t.routes.length?d:t.routes.length-1;const s=typeof t.type==="string"?t.type:void 0;const r=s!=="tab"&&s!=="drawer";for(let i=0;i<t.routes.length;i++){if(!r&&i!==R)continue;const c=t.routes[i];const h=i===R;let u=c.name;if(c.name==="index"){u="/"}else if(!u.startsWith("/")){u=`/${u}`}if(n&&n!=="/"){u=`${n}${u}`}if(c.params){const S=Object.entries(c.params);if(S.length>0){u=u.replace(/\[([^\]]+)\]/g,(v,b)=>{return c.params[b]||v})}}const y=f&&h;const k=y&&c.state?collectRoutesFromState(c.state,e+1,u,true):[];p.push({key:c.key,name:c.name,path:u,params:c.params||{},state:c.state,isFocused:y&&k.length===0});p.push(...k)}return p}function buildStack(t,e){if(!t)return[];try{const n=collectRoutesFromState(t);const f=e?n.filter(s=>{if(s.name.startsWith("__"))return false;if(s.name.includes("_layout"))return false;if(s.name.startsWith("+not-found"))return false;return true}):n;const p=f.length>0?f:n.slice(-1);const d=p.findIndex(s=>s.isFocused);const R=d>=0?d:p.length-1;return p.map((s,r)=>{let i=s.path||`/${s.name}`;if(e){i=i.replace(/^\/__root/,"")}if(!i||i===""){i="/"}return{key:s.key,name:s.name,pathname:i,params:s.params||{},isFocused:r===R,index:r,canPop:r>0}})}catch(n){console.error("[Buoy]","Error transforming navigation state:",n);return[]}}function useNavigationStack(){const t=(0,_sharedUi.isExpoRouterAvailable)();const e=(0,_safeReactNavigation.useSafeNavigationContainerRef)();const[n,f]=(0,_react.useState)(()=>e?.getRootState?.()??null);const[p,d]=(0,_react.useState)(false);const[R,s]=(0,_react.useState)(null);(0,_react.useEffect)(()=>{if(!e)return;const o=e.getRootState?.();if(o){f(o)}d(true);const l=e.addListener?.("state",()=>{const a=e.getRootState?.();if(a){f(a)}});return()=>{l?.()}},[e]);const r=(0,_react.useMemo)(()=>buildStack(n,t),[n,t]);const i=(0,_react.useMemo)(()=>{return r.find(o=>o.isFocused)||null},[r]);const c=r.length;const h=c<=1;const u=(0,_react.useCallback)(()=>{if(!e)return;const o=e.getRootState?.();if(o){f(o)}},[e]);const y=(0,_react.useCallback)(o=>{if(o>=r.length||o<0)return;const l=r[o];if(!l)return;try{const a=(0,_sharedUi.getSafeRouter)();if(a){a.navigate(l.pathname)}else if(e){const g=e.getRootState?.();if(g){const m=findScreenPath(g,l.name);if(m){const x=buildNestedNavigateAction(m);if(x){e.dispatch(x);return}}}e.dispatch(CommonActions.navigate({name:l.name,params:l.params}))}}catch(a){console.error("[Buoy]","Failed to navigate:",a)}},[r,e]);const k=(0,_react.useCallback)((o,l)=>{if(!e)return false;try{const a=e.getRootState?.();if(!l&&a){const g=findScreenPath(a,o);if(g){const m=buildNestedNavigateAction(g);if(m){e.dispatch(m);return true}}}e.dispatch(CommonActions.navigate({name:o,params:l}));return true}catch(a){console.error("[Buoy]","Failed to navigate:",a);return false}},[e]);const S=(0,_react.useCallback)(o=>{if(o>=r.length||o<0)return;const l=r.length-1;const a=l-o;if(a<=0)return;try{const g=(0,_sharedUi.getSafeRouter)();if(g){for(let m=0;m<a;m++){g.back()}}else if(e){e.dispatch(StackActions.pop(a))}}catch(g){console.error("[Buoy]","Failed to pop:",g)}},[r,e]);const v=(0,_react.useCallback)(()=>{if(h)return;try{const o=(0,_sharedUi.getSafeRouter)();if(o){o.back()}else if(e){e.goBack()}}catch(o){console.error("[Buoy]","Failed to go back:",o)}},[h,e]);const b=(0,_react.useCallback)(()=>{if(h)return;try{const o=(0,_sharedUi.getSafeRouter)();if(o){S(0)}else if(e){e.dispatch(StackActions.popToTop())}}catch(o){console.error("[Buoy]","Failed to pop to top:",o)}},[h,e,S]);return{stack:r,focusedRoute:i,stackDepth:c,isAtRoot:h,isLoaded:p,error:R,refresh:u,navigateToIndex:y,navigateToRoute:k,popToIndex:S,goBack:v,popToTop:b}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.getCommonActions=getCommonActions;exports.getStackActions=getStackActions;exports.isReactNavigationAvailable=isReactNavigationAvailable;exports.useSafeNavigation=useSafeNavigation;exports.useSafeNavigationContainerRef=useSafeNavigationContainerRef;exports.useSafeNavigationState=useSafeNavigationState;var _react=require("react");let reactNavigation=null;let isAvailable=false;let checkedAvailability=false;let vendoredReactNavigation=null;let checkedVendored=false;function getVendoredReactNavigation(){if(checkedVendored)return vendoredReactNavigation;checkedVendored=true;try{const e=require("expo-router/react-navigation");vendoredReactNavigation=e?.NavigationContainerRefContext?e:null}catch{vendoredReactNavigation=null}return vendoredReactNavigation}function checkReactNavigationAvailability(){if(checkedAvailability)return isAvailable;try{reactNavigation=require("@react-navigation/native");isAvailable=reactNavigation!=null}catch(e){isAvailable=false;reactNavigation=null}if(!isAvailable){const e=getVendoredReactNavigation();if(e){reactNavigation=e;isAvailable=true}}checkedAvailability=true;return isAvailable}function noOpUseNavigation(){return(0,_react.useMemo)(()=>({navigate:()=>console.warn("[route-events] @react-navigation/native not installed: navigate() unavailable"),goBack:()=>console.warn("[route-events] @react-navigation/native not installed: goBack() unavailable"),canGoBack:()=>false,reset:()=>console.warn("[route-events] @react-navigation/native not installed: reset() unavailable"),setParams:()=>console.warn("[route-events] @react-navigation/native not installed: setParams() unavailable"),dispatch:()=>console.warn("[route-events] @react-navigation/native not installed: dispatch() unavailable"),isFocused:()=>true,addListener:()=>()=>{},removeListener:()=>{},getParent:()=>void 0,getState:()=>void 0,getId:()=>void 0}),[])}function noOpUseNavigationState(e){return(0,_react.useMemo)(()=>{const t={key:"default",index:0,routeNames:[],routes:[],type:"stack"};try{return e?e(t):t}catch{return t}},[e])}function useSafeNavigation(){if(!checkReactNavigationAvailability()){return noOpUseNavigation()}try{return reactNavigation.useNavigation()}catch(e){console.warn("[route-events] Failed to use @react-navigation/native.useNavigation:",e);return noOpUseNavigation()}}function useSafeNavigationState(e){if(!checkReactNavigationAvailability()){return noOpUseNavigationState(e)}try{return reactNavigation.useNavigationState(e)}catch(t){console.warn("[route-events] Failed to use @react-navigation/native.useNavigationState:",t);return noOpUseNavigationState(e)}}const FallbackNavigationContainerRefContext=(0,_react.createContext)(void 0);function getCommonActions(){return checkReactNavigationAvailability()?reactNavigation.CommonActions:null}function getStackActions(){return checkReactNavigationAvailability()?reactNavigation.StackActions:null}let npmContainerRefContext=null;let vendoredContainerRefContext=null;function getContainerRefContexts(){if(npmContainerRefContext==null){npmContainerRefContext=checkReactNavigationAvailability()&&reactNavigation.NavigationContainerRefContext?reactNavigation.NavigationContainerRefContext:FallbackNavigationContainerRefContext}if(vendoredContainerRefContext==null){const e=getVendoredReactNavigation();vendoredContainerRefContext=e?.NavigationContainerRefContext??FallbackNavigationContainerRefContext}return[npmContainerRefContext,vendoredContainerRefContext]}function useSafeNavigationContainerRef(){const[e,t]=getContainerRefContexts();const n=(0,_react.useContext)(e);const a=(0,_react.useContext)(t);return n??a}function isReactNavigationAvailable(){return checkReactNavigationAvailability()}
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.getCommonActions=getCommonActions;exports.getStackActions=getStackActions;exports.isReactNavigationAvailable=isReactNavigationAvailable;exports.useSafeNavigation=useSafeNavigation;exports.useSafeNavigationContainerRef=useSafeNavigationContainerRef;exports.useSafeNavigationState=useSafeNavigationState;var _react=require("react");let reactNavigation=null;let isAvailable=false;let checkedAvailability=false;let vendoredReactNavigation=null;let checkedVendored=false;function getVendoredReactNavigation(){if(checkedVendored)return vendoredReactNavigation;checkedVendored=true;try{const e=require("expo-router/react-navigation");vendoredReactNavigation=e?.NavigationContainerRefContext?e:null}catch{vendoredReactNavigation=null}return vendoredReactNavigation}function checkReactNavigationAvailability(){if(checkedAvailability)return isAvailable;try{reactNavigation=require("@react-navigation/native");isAvailable=reactNavigation!=null}catch(e){isAvailable=false;reactNavigation=null}if(!isAvailable){const e=getVendoredReactNavigation();if(e){reactNavigation=e;isAvailable=true}}checkedAvailability=true;return isAvailable}function noOpUseNavigation(){return(0,_react.useMemo)(()=>({navigate:()=>console.warn("[Buoy]","[route-events] @react-navigation/native not installed: navigate() unavailable"),goBack:()=>console.warn("[Buoy]","[route-events] @react-navigation/native not installed: goBack() unavailable"),canGoBack:()=>false,reset:()=>console.warn("[Buoy]","[route-events] @react-navigation/native not installed: reset() unavailable"),setParams:()=>console.warn("[Buoy]","[route-events] @react-navigation/native not installed: setParams() unavailable"),dispatch:()=>console.warn("[Buoy]","[route-events] @react-navigation/native not installed: dispatch() unavailable"),isFocused:()=>true,addListener:()=>()=>{},removeListener:()=>{},getParent:()=>void 0,getState:()=>void 0,getId:()=>void 0}),[])}function noOpUseNavigationState(e){return(0,_react.useMemo)(()=>{const t={key:"default",index:0,routeNames:[],routes:[],type:"stack"};try{return e?e(t):t}catch{return t}},[e])}function useSafeNavigation(){if(!checkReactNavigationAvailability()){return noOpUseNavigation()}try{return reactNavigation.useNavigation()}catch(e){console.warn("[Buoy]","[route-events] Failed to use @react-navigation/native.useNavigation:",e);return noOpUseNavigation()}}function useSafeNavigationState(e){if(!checkReactNavigationAvailability()){return noOpUseNavigationState(e)}try{return reactNavigation.useNavigationState(e)}catch(t){console.warn("[Buoy]","[route-events] Failed to use @react-navigation/native.useNavigationState:",t);return noOpUseNavigationState(e)}}const FallbackNavigationContainerRefContext=(0,_react.createContext)(void 0);function getCommonActions(){return checkReactNavigationAvailability()?reactNavigation.CommonActions:null}function getStackActions(){return checkReactNavigationAvailability()?reactNavigation.StackActions:null}let npmContainerRefContext=null;let vendoredContainerRefContext=null;function getContainerRefContexts(){if(npmContainerRefContext==null){npmContainerRefContext=checkReactNavigationAvailability()&&reactNavigation.NavigationContainerRefContext?reactNavigation.NavigationContainerRefContext:FallbackNavigationContainerRefContext}if(vendoredContainerRefContext==null){const e=getVendoredReactNavigation();vendoredContainerRefContext=e?.NavigationContainerRefContext??FallbackNavigationContainerRefContext}return[npmContainerRefContext,vendoredContainerRefContext]}function useSafeNavigationContainerRef(){const[e,t]=getContainerRefContexts();const n=(0,_react.useContext)(e);const a=(0,_react.useContext)(t);return n??a}function isReactNavigationAvailable(){return checkReactNavigationAvailability()}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";export class RouteObserver{listeners=new Set;emit(e){this.listeners.forEach(r=>{try{r(e)}catch(t){console.error("[RouteObserver] Error in listener:",t)}})}addListener(e){this.listeners.add(e);return()=>this.listeners.delete(e)}removeListener(e){this.listeners.delete(e)}}export const routeObserver=new RouteObserver;
|
|
1
|
+
"use strict";export class RouteObserver{listeners=new Set;emit(e){this.listeners.forEach(r=>{try{r(e)}catch(t){console.error("[Buoy]","[RouteObserver] Error in listener:",t)}})}addListener(e){this.listeners.add(e);return()=>this.listeners.delete(e)}removeListener(e){this.listeners.delete(e)}}export const routeObserver=new RouteObserver;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";const
|
|
1
|
+
"use strict";const n=new Map;let u=null;export function registerBrowserRoutes(e){for(const t of e)n.set(t,(n.get(t)??0)+1);u=Date.now();let s=true;return()=>{if(!s)return;s=false;for(const t of e){const c=(n.get(t)??1)-1;if(c)n.set(t,c);else n.delete(t)}u=Date.now()}}export function getBrowserRoutePaths(){return[...n.keys()]}export function getBrowserRoutesUpdatedAt(){return u}export function getBrowserRouteInfo(e){const s={segments:e.split("/").filter(Boolean),params:{}};const t=getBrowserRoutePaths();if(t.includes(e))return s;for(const c of t){const i=c.split("/").filter(Boolean);const f=[];const g=i.map(r=>{const o=/^\[(\.\.\.)?([^\]]+)\]$/.exec(r);if(!o)return r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");f.push({name:o[2],deep:!!o[1]});return o[1]?"(.+)":"([^/]+)"});const l=new RegExp("^/"+g.join("/")+"/?$").exec(e);if(!l)continue;const p=r=>{try{return decodeURIComponent(r)}catch{return r}};const d={};f.forEach(({name:r,deep:o},m)=>{const w=l[m+1];d[r]=o?w.split("/").map(p):p(w)});return{segments:i,params:d}}return s}let a=0;export function claimBrowserRouteEvents(){a++;let e=true;return()=>{if(e){e=false;a--}}}export function hasBrowserRouteEventSource(){return a>0}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{browserRouter as g,getBrowserHref as B,getBrowserRouteURL as k,subscribeBrowserNavigation as I}from"@buoy-gg/shared-ui/utils";import{routeObserver as j}from"./RouteObserver";import{routeEventStore as
|
|
1
|
+
"use strict";import{browserRouter as g,getBrowserHref as B,getBrowserRouteURL as k,subscribeBrowserNavigation as I}from"@buoy-gg/shared-ui/utils";import{routeObserver as j}from"./RouteObserver";import{routeEventStore as E}from"./stores/routeEventStore";import{navigationStackStore as l}from"./stores/navigationStackStore";import{getBrowserRouteInfo as v,hasBrowserRouteEventSource as P}from"./browserRouteRegistry";let R=0;let d;export function startBrowserRouteCapture(){if(typeof window==="undefined")return()=>{};if(R++===0){E.hydrateBootCapture();let y;let m;let w="";const o=[];let r=-1;const S=()=>{const e=window.history.state;if(!e||typeof e!=="object")return void 0;const t=e.key??e.__TSR_key;return typeof t==="string"||typeof t==="number"?String(t):void 0};const T=e=>{for(let t=r-1;t>=0;t--)if(o[t].href===e)return t;for(let t=r+1;t<o.length;t++)if(o[t].href===e)return t;return-1};const b=e=>{const t=S();if(e.href===w&&e.kind==="pop"&&(t===void 0||o[r]?.key===t))return;if(e.kind==="replace"&&r>=0)o[r]={href:e.href,key:t};else if(e.kind==="pop"){const f=t===void 0?-1:o.findIndex(i=>i.key===t);const n=f>=0?f:T(e.href);if(n>=0)r=n;else{o.splice(r+1);o.push({href:e.href,key:t});r++}}else{o.splice(r+1);o.push({href:e.href,key:t});r++}w=e.href;const s=k(e.href);const a=Date.now();const p=v(s.pathname);if(!P())j.emit({pathname:s.pathname,params:{...p.params,...Object.fromEntries(s.searchParams)},segments:p.segments,previousPathname:y,timestamp:a,timeSincePrevious:m===void 0?void 0:a-m});y=s.pathname;m=a;l.setStack(o.slice(0,r+1).map(({href:f},n)=>{const i=k(f);const u=v(i.pathname);return{key:`browser:${n}`,name:u.segments.join("/")||"index",pathname:i.pathname,params:{...u.params,...Object.fromEntries(i.searchParams)},index:n,isFocused:n===r,canPop:n>0}}))};const c=e=>{if(!Number.isInteger(e)||e<0||e>=o.length)throw new Error("That browser history entry is unavailable.");window.history.go(e-r)};l.setActions({navigateToIndex:c,popToIndex:c,goBack:g.back,popToTop:()=>c(0),navigateToRoute:(e,t)=>{const s={...t};const a=`/${e.replace(/^\//,"")}`.replace(/\[(\.\.\.)?([^\]]+)\]/g,(p,f,n)=>{if(!(n in s))return p;const i=s[n];delete s[n];return f&&Array.isArray(i)?i.map(u=>encodeURIComponent(String(u))).join("/"):encodeURIComponent(String(i))});g.push({pathname:a==="/index"?"/":a,params:s});return true}});d=I(b);b({href:B(),kind:"initial"})}let h=false;return()=>{if(h)return;h=true;if(--R===0){d?.();d=void 0;l.setActions(null)}}}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
"use strict";import{useState as
|
|
1
|
+
"use strict";import{useState as L,useMemo as D,useEffect as V}from"react";import{View as n,Text as r,ScrollView as q,TouchableOpacity as I,StyleSheet as K,Alert as T}from"react-native";import{ChevronDown as Q,ChevronRight as X,InlineCopyButton as Y,ProUpgradeModal as Z,buoyColors as F,night as a,useSafeAreaInsets as ee,ToolEmptyState as te,monoFont as d}from"@buoy-gg/shared-ui";import{useIsPro as oe}from"@buoy-gg/license";import{DataViewer as ne}from"@buoy-gg/shared-ui/dataViewer";import{useNavigationStack as ae}from"../useNavigationStack";import{stackItemTestID as re}from"../utils/testIDs";import{jsx as o,jsxs as i}from"react/jsx-runtime";export function NavigationStack({style:B,injectedStack:R,onAction:y,onCopyValueChange:$}){const f=ae();const v=R!=null;const E=ee({minBottom:8});const s=v?R:f.stack;const j=v?true:f.isLoaded;const w=v?null:f.error;const P=D(()=>s.find(t=>t.isFocused)??null,[s]);const h=s.length;const k=h<=1;const H=t=>y?y("navigateToIndex",{index:t}):f.navigateToIndex(t);const O=t=>y?y("popToIndex",{index:t}):f.popToIndex(t);const G=()=>y?y("goBack"):f.goBack();const M=()=>y?y("popToTop"):f.popToTop();const[u,U]=L(null);const[C,m]=L(false);const x=oe();V(()=>{if(C&&x){m(false)}},[C,x]);const z=D(()=>{const t=s.map(c=>({pathname:c.pathname,name:c.name,params:c.params,isFocused:c.isFocused}));return JSON.stringify(t,null,2)},[s]);V(()=>{$?.(z)},[z,$]);const g=D(()=>{if(u!==null&&s[u]){return s[u]}return P},[u,s,P]);const se=D(()=>{return u!==null&&s[u]&&!s[u].isFocused},[u,s]);if(!j){return o(n,{style:[e.container,B],children:o(n,{style:e.loadingContainer,children:o(r,{style:e.loadingText,testID:"buoy-routes-stack-loading",children:"Loading navigation stack..."})})})}if(w){return o(n,{style:[e.container,B],children:i(n,{style:e.errorContainer,testID:"buoy-routes-stack-error",children:[o(r,{style:e.errorText,children:"Error loading stack"}),o(r,{style:e.errorDetail,testID:"buoy-routes-stack-error-detail",children:w.message})]})})}if(s.length===0){return o(n,{style:[e.container,B],children:o(te,{testID:"buoy-routes-stack-empty",otto:"walking",title:"No navigation stack",message:"Navigate to a route to see the stack"})})}const W=(t,c,l,b)=>{if(y){const S=globalThis.window?.confirm;if(!S||S(`${t}
|
|
2
2
|
|
|
3
|
-
${
|
|
3
|
+
${c}`)){b()}return}T.alert(t,c,[{text:"Cancel",style:"cancel"},{text:l,style:"destructive",onPress:b}])};const _=()=>{if(!x){m(true);return}if(k){T.alert("Cannot Go Back","Already at the root of the stack");return}G()};const ie=()=>{if(!x){m(true);return}if(k){T.alert("Already at Top","Stack only has one screen");return}W("Pop to Top","This will remove all screens except the root screen.","Pop to Top",M)};const N=t=>{U(u===t?null:t)};const A=()=>{if(!x){m(true);return}if(!g)return;if(g.isFocused){T.alert("Already There","This route is already visible");return}H(g.index)};const J=()=>{if(!x){m(true);return}if(!g)return;if(g.isFocused){T.alert("Cannot Pop","Selected route is already visible");return}if(g.index===h-1){T.alert("Cannot Pop","No screens above selected route");return}const t=h-1-g.index;const c=g.index;W("Pop to Route",`Remove ${t} screen${t!==1?"s":""} above ${g.pathname}?`,"Pop",()=>O(c))};return i(n,{style:[e.container,B],children:[o(q,{testID:"buoy-routes-stack-scroll",style:e.stackScroll,contentContainerStyle:[e.stackContent,{paddingBottom:e.stackContent.padding+E.bottom}],children:[...s].reverse().map((t,c)=>{const l=s.length-1-c;const b=u===l;const S=Object.keys(t.params).length>0;const p=re(l);return o(n,{style:e.stackItemWrapper,testID:p,children:i(n,{style:[e.stackItem,b&&e.stackItemSelected],children:[i(n,{style:e.stackItemHeader,children:[i(I,{style:e.stackItemToggle,onPress:()=>N(l),activeOpacity:.7,testID:`${p}-toggle`,accessibilityRole:"button",accessibilityLabel:`${t.pathname}, ${t.isFocused?"focused":"mounted"}, position ${l} of ${h-1}`,children:[o(n,{style:e.expandIndicator,children:b?o(Q,{size:14,color:a.color.textSecondary}):o(X,{size:14,color:a.color.textSecondary})}),o(r,{style:e.stackItemPath,numberOfLines:1,testID:`${p}-path`,children:t.pathname})]}),o(Y,{value:t.pathname,buttonStyle:e.copyRouteButton,testID:`${p}-copy`}),o(I,{onPress:()=>N(l),activeOpacity:.7,accessible:false,style:[e.statusBadge,{backgroundColor:t.isFocused?`${F.success}15`:"#3B82F615",borderColor:t.isFocused?`${F.success}40`:"#3B82F640"}],children:o(r,{style:[e.statusBadgeText,{color:t.isFocused?F.success:"#3B82F6"}],testID:`${p}-status`,children:t.isFocused?"FOCUSED":"MOUNTED"})})]}),b&&i(n,{style:e.expandedContent,children:[i(n,{style:e.detailRow,children:[o(r,{style:e.detailLabel,children:"Route Name:"}),o(r,{style:e.detailValue,testID:`${p}-name`,children:t.name})]}),i(n,{style:e.detailRow,children:[o(r,{style:e.detailLabel,children:"Position:"}),i(r,{style:e.detailValue,testID:`${p}-position`,children:[l," / ",h-1]})]}),S&&o(n,{style:e.dataViewerContainer,children:o(ne,{title:"Parameters",data:t.params,showTypeFilter:false})}),i(n,{style:e.actionsRow,children:[i(n,{style:e.actionWrapper,children:[o(I,{style:[e.actionButton,k&&e.actionButtonDisabled],onPress:_,disabled:k,testID:`${p}-back`,accessibilityRole:"button",accessibilityLabel:"Go back one screen",children:o(r,{style:[e.actionButtonText,k&&e.actionButtonTextDisabled],children:"Back"})}),o(r,{style:e.helpText,children:"Go back one screen"})]}),i(n,{style:e.actionWrapper,children:[o(I,{style:[e.actionButton,t.isFocused&&e.actionButtonDisabled],onPress:A,disabled:t.isFocused,testID:`${p}-go`,accessibilityRole:"button",accessibilityLabel:`Navigate to ${t.pathname}`,children:o(r,{style:[e.actionButtonText,t.isFocused&&e.actionButtonTextDisabled],children:"Go"})}),o(r,{style:e.helpText,children:"Navigate to this route"})]}),i(n,{style:e.actionWrapper,children:[o(I,{style:[e.actionButton,(t.isFocused||l===h-1)&&e.actionButtonDisabled],onPress:J,disabled:t.isFocused||l===h-1,testID:`${p}-pop-to`,accessibilityRole:"button",accessibilityLabel:`Remove screens above ${t.pathname}`,children:o(r,{style:[e.actionButtonText,(t.isFocused||l===h-1)&&e.actionButtonTextDisabled],children:"Pop To"})}),o(r,{style:e.helpText,children:"Remove screens above this"})]})]})]})]})},`stack-${l}-${t.key}`)})}),o(Z,{visible:C,onClose:()=>m(false),featureName:"Stack Navigation"})]})}const e=K.create({container:{flex:1,backgroundColor:"transparent"},loadingContainer:{flex:1,justifyContent:"center",alignItems:"center",padding:32},loadingText:{color:a.color.textSecondary,fontSize:14,fontFamily:d},errorContainer:{flex:1,justifyContent:"center",alignItems:"center",padding:32},errorText:{color:F.error,fontSize:16,fontWeight:"600",fontFamily:d,marginBottom:8},errorDetail:{color:a.color.textSecondary,fontSize:12,fontFamily:d,textAlign:"center"},emptyContainer:{flex:1,justifyContent:"center",alignItems:"center",padding:32},emptyText:{color:a.color.text,fontSize:16,fontWeight:"600",fontFamily:d,marginBottom:8},emptySubtext:{color:a.color.textSecondary,fontSize:14,fontFamily:d,textAlign:"center"},stackScroll:{flex:1},stackContent:{padding:8},stackItemWrapper:{marginBottom:6},stackItem:{backgroundColor:a.color.surface,borderRadius:6,borderWidth:1,borderColor:a.color.border,overflow:"hidden"},stackItemSelected:{borderColor:a.color.accent,borderWidth:2},stackItemHeader:{flexDirection:"row",alignItems:"center",paddingVertical:10,paddingHorizontal:12,gap:8},stackItemToggle:{flex:1,flexDirection:"row",alignItems:"center",gap:8},expandIndicator:{width:20,alignItems:"center"},stackItemPath:{fontSize:13,fontWeight:"600",color:a.color.text,fontFamily:d,flex:1},copyRouteButton:{padding:4,marginLeft:4},statusBadge:{borderRadius:4,paddingHorizontal:6,paddingVertical:2,borderWidth:1},statusBadgeText:{fontSize:10,fontWeight:"600",fontFamily:d},expandedContent:{paddingHorizontal:12,paddingTop:8,paddingBottom:12,borderTopWidth:1,borderTopColor:a.color.border},detailRow:{marginBottom:8},detailLabel:{fontSize:10,color:a.color.textSecondary,fontFamily:d,marginBottom:2},detailValue:{fontSize:12,color:a.color.text,fontFamily:d},dataViewerContainer:{marginTop:4,marginHorizontal:-12,marginBottom:8},actionsRow:{flexDirection:"row",gap:6,marginTop:12},actionWrapper:{flex:1},actionButton:{backgroundColor:a.color.surfaceElevated,paddingVertical:8,paddingHorizontal:8,borderRadius:6,alignItems:"center"},actionButtonDisabled:{opacity:.5},actionButtonText:{fontSize:12,fontWeight:"600",color:a.color.text,fontFamily:d},actionButtonTextDisabled:{color:a.color.textTertiary},helpText:{fontSize:9,color:a.color.textSecondary,fontFamily:d,textAlign:"center",marginTop:4,lineHeight:12}});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{View as o,Text as
|
|
1
|
+
"use strict";import{View as o,Text as a,StyleSheet as y}from"react-native";import{InlineCopyButton as n,night as d,monoFont as u}from"@buoy-gg/shared-ui";import{DataViewer as h}from"@buoy-gg/shared-ui/dataViewer";import{jsx as l,jsxs as i}from"react/jsx-runtime";function m(t){if(t<1e3){return`${t}ms`}if(t<6e4){return`${(t/1e3).toFixed(1)}s`}const r=Math.floor(t/6e4);const s=(t%6e4/1e3).toFixed(0);return`${r}m ${s}s`}export function RouteEventExpandedContent({event:t,visitNumber:r,routeTemplate:s}){const c=t.params&&Object.keys(t.params).length>0;return i(o,{style:e.container,children:[i(o,{style:e.section,children:[t.routeName&&i(o,{style:e.detailRow,children:[l(a,{style:e.detailLabel,children:"Name:"}),l(a,{style:e.detailValue,testID:"buoy-routes-detail-name",children:t.routeName})]}),t.matchedPath&&i(o,{style:e.detailRow,children:[l(a,{style:e.detailLabel,children:"Match:"}),l(a,{style:e.detailValue,testID:"buoy-routes-detail-match",children:t.matchedPath})]}),s&&i(o,{style:e.detailRow,testID:"buoy-routes-detail-template",children:[l(a,{style:e.detailLabel,children:"Template:"}),l(a,{style:e.detailValue,testID:"buoy-routes-detail-template-value",children:s}),l(n,{value:s,buttonStyle:e.copyButton})]}),t.previousPathname&&i(o,{style:e.detailRow,testID:"buoy-routes-detail-from",children:[l(a,{style:e.detailLabel,children:"From:"}),l(a,{style:e.detailValue,testID:"buoy-routes-detail-from-value",children:t.previousPathname}),l(n,{value:t.previousPathname,buttonStyle:e.copyButton})]}),i(o,{style:e.detailRow,testID:"buoy-routes-detail-to",children:[l(a,{style:e.detailLabel,children:"To:"}),l(a,{style:e.detailValue,testID:"buoy-routes-detail-to-value",children:t.pathname}),l(n,{value:t.pathname,buttonStyle:e.copyButton})]})]}),i(o,{style:e.section,children:[t.timeSincePrevious!==void 0&&i(o,{style:e.detailRow,testID:"buoy-routes-detail-duration",children:[l(a,{style:e.detailLabel,children:"Duration:"}),l(a,{style:e.detailValue,testID:"buoy-routes-detail-duration-value",children:m(t.timeSincePrevious)})]}),i(o,{style:e.detailRow,testID:"buoy-routes-detail-time",children:[l(a,{style:e.detailLabel,children:"Time:"}),l(a,{style:e.detailValue,testID:"buoy-routes-detail-time-value",children:new Date(t.timestamp).toLocaleString()})]})]}),i(o,{style:e.section,children:[t.segments&&t.segments.length>0&&i(o,{style:e.detailRow,testID:"buoy-routes-detail-segments",children:[l(a,{style:e.detailLabel,children:"Segments:"}),l(a,{style:e.detailValue,testID:"buoy-routes-detail-segments-value",children:t.segments.join(" \u2192 ")}),l(n,{value:JSON.stringify(t.segments),buttonStyle:e.copyButton})]}),c&&i(o,{style:e.dataViewerContainer,children:[i(o,{style:e.dataViewerHeader,children:[i(a,{style:e.dataViewerTitle,testID:"buoy-routes-detail-params-title",children:["Parameters (",Object.keys(t.params).length,")"]}),l(n,{value:JSON.stringify(t.params,null,2),buttonStyle:e.copyButton})]}),l(h,{data:t.params,title:"",showTypeFilter:true,rawMode:true,initialExpanded:true})]}),r>1&&i(o,{style:e.detailRow,testID:"buoy-routes-detail-visited",children:[l(a,{style:e.detailLabel,children:"Visited:"}),i(a,{style:e.detailValue,testID:"buoy-routes-detail-visited-value",children:[r," time",r!==1?"s":""]})]})]})]})}const e=y.create({container:{gap:12},section:{gap:8},detailRow:{flexDirection:"row",alignItems:"center",gap:8},detailLabel:{fontSize:10,color:d.color.textSecondary,fontFamily:u,fontWeight:"600",minWidth:70},detailValue:{fontSize:11,color:d.color.text,fontFamily:u,flex:1},copyButton:{padding:4,borderRadius:4},dataViewerContainer:{marginTop:4},dataViewerHeader:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",marginBottom:8},dataViewerTitle:{fontSize:11,color:d.color.textSecondary,fontFamily:u,fontWeight:"600"}});
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
-
"use strict";import{useState as B,useCallback as w,useMemo as
|
|
1
|
+
"use strict";import{useState as B,useCallback as w,useMemo as E,useEffect as he}from"react";import{night as o,ToolEmptyState as ye,monoFont as d}from"@buoy-gg/shared-ui";import{View as n,Text as l,TextInput as ge,TouchableOpacity as C,ScrollView as fe,StyleSheet as me,Alert as S,Platform as be}from"react-native";import{isCapacitorNative as xe}from"@buoy-gg/license";import{useSafeRouter as Ce}from"@buoy-gg/shared-ui";import{Search as Y,ChevronDown as ee,ChevronRight as te,Home as Se,InlineCopyButton as De,CopyButton as Ie,RefreshCw as Te,formatRelativeTime as Be,ProUpgradeModal as Re}from"@buoy-gg/shared-ui";import{useIsPro as Le}from"@buoy-gg/license";import{useRouteSitemap as we}from"../useRouteSitemap";import{sitemapGroupTestID as oe,sitemapRouteTestID as ze}from"../utils/testIDs";import{jsx as t,jsxs as i}from"react/jsx-runtime";const p=be.OS==="web"&&!xe();const P=p?22:16;const $e={path:"/",name:"index",type:"index",params:[],nodeType:"route",contextKey:"/",isInternal:false,children:[],depth:0};export function RoutesSitemap({style:r,injectedRoutes:f,injectedSource:m,injectedLastUpdatedAt:D,onNavigateRoute:b}){const[u,I]=B("");const[z,g]=B(false);const[$,V]=B(new Set(["Static Routes","Dynamic Routes"]));const[x,W]=B(false);const[j,O]=B(false);const v=Le();he(()=>{if(j&&v){O(false)}},[j,v]);const L=Ce();const{groups:k,stats:h,isLoaded:ae,isSupported:ne,filteredRoutes:N,routes:K,refresh:Q,lastUpdatedAt:G,source:A}=we({searchQuery:u,sortBy:"path",injectedRoutes:f,injectedSource:m,injectedLastUpdatedAt:D});const ie=E(()=>{return{summary:{total:h.total,static:h.static,dynamic:h.dynamic,layouts:h.layouts,groups:h.groups,timestamp:new Date().toISOString()},groups:k.map(a=>({title:a.title,description:a.description,count:a.routes.length,routes:a.routes.map(s=>({path:s.path,name:s.name,type:s.type,params:s.params,depth:s.depth,hasChildren:s.children.length>0,childrenCount:s.children.length}))})),allRoutes:K.map(a=>a.path)}},[k,h,K]);const le=w(a=>{V(s=>{const y=new Set(s);if(y.has(a)){y.delete(a)}else{y.add(a)}return y})},[]);const H=w((a,s=0,y={})=>{const M=a.params;if(s>=M.length){let c=a.path;Object.entries(y).forEach(([T,X])=>{if(a.type==="catch-all"){c=c.replace(`[...${T}]`,X)}else{c=c.replace(`[${T}]`,X)}});try{L.push(c)}catch(T){S.alert("Navigation Error",String(T))}return}const F=M[s];const q=a.type==="catch-all"?`[...${F}]`:`[${F}]`;const _="Enter Parameter Value";const J=`Enter value for ${q}:
|
|
2
2
|
|
|
3
|
-
Route: ${a.path}`,[{text:"Cancel",style:"cancel"},{text:s<U.length-1?"Next":"Navigate",onPress:m=>{if(m&&m.trim()){const I={...y,[M]:m.trim()};G(a,s+1,I)}else{T.alert("Invalid Value","Please enter a value for the parameter")}}}],"plain-text")},[L]);const A=w((a,s)=>{if(b){b(a);return}if(!$&&!s?.bypassPro){V(true);return}if(a.type==="layout"||a.type==="group"){T.alert("Cannot Navigate",`${a.type==="layout"?"Layouts":"Route groups"} are not navigable routes`);return}if(a.type==="dynamic"||a.type==="catch-all"){if(a.params.length===0){try{L.push(a.path)}catch(y){T.alert("Navigation Error",String(y))}return}G(a);return}try{L.push(a.path)}catch(y){T.alert("Navigation Error",String(y))}},[L,G,$,b]);const ne=w(()=>{A(Le,{bypassPro:true})},[A]);const ie=w(()=>{if(x)return;W(true);K();setTimeout(()=>W(false),400)},[x,K]);const le=H(()=>{if(!O)return"Awaiting route data";return`Updated ${De(O)}`},[O]);const se=H(()=>{if(!N)return"Source: unknown";return`Source: ${N}`},[N]);const Q=H(()=>{if(p&&j.length>0){return[{title:"Search Results",icon:"",routes:j}]}return k},[p,j,k]);if(!te){return t(n,{style:[e.container,r],children:t(n,{style:e.loadingContainer,children:t(l,{style:e.loadingText,testID:"buoy-routes-sitemap-loading",children:oe?"Loading routes...":"Route sitemap isn't available on the dashboard \u2014 the route tree lives on the device. Use the Events tab to see navigation here."})})})}return i(n,{style:[e.container,r],children:[z&&i(n,{style:e.searchContainer,testID:"buoy-routes-sitemap-search-field",children:[t(q,{size:16,color:o.color.textTertiary}),t(ue,{style:e.searchInput,placeholder:"Search routes...",placeholderTextColor:o.color.placeholder,value:p,onChangeText:D,autoCapitalize:"none",autoCorrect:false,autoFocus:true,testID:"buoy-routes-sitemap-search",accessibilityLabel:"Search routes"}),p.length>0&&t(C,{onPress:()=>D(""),style:e.clearButton,testID:"buoy-routes-sitemap-search-clear",accessibilityRole:"button",accessibilityLabel:"Clear route search",children:t(l,{style:e.clearButtonText,children:"\u2715"})}),t(C,{style:e.closeSearchButton,onPress:()=>{h(false);D("")},testID:"buoy-routes-sitemap-search-done",accessibilityRole:"button",accessibilityLabel:"Done searching routes",children:t(l,{style:e.closeSearchText,children:"Done"})})]}),i(he,{testID:"buoy-routes-sitemap-scroll",style:e.scrollView,contentContainerStyle:e.scrollContent,children:[!z&&i(n,{style:e.header,children:[i(n,{style:e.actionsRow,children:[i(n,{style:[e.actionWrapper,d&&e.actionWrapperDesktop],children:[t(C,{style:[e.iconButton,d&&e.iconButtonDesktop],onPress:ne,accessibilityLabel:"Go to home route",accessibilityRole:"button",testID:"buoy-routes-sitemap-home",children:t(be,{size:F,color:o.color.textSecondary})}),t(l,{style:[e.actionLabel,d&&e.actionLabelDesktop],children:"Home"})]}),i(n,{style:[e.actionWrapper,d&&e.actionWrapperDesktop],children:[t(Ce,{value:re,testID:"buoy-routes-sitemap-copy",size:d?F:14,buttonStyle:d?e.actionButtonHeaderDesktop:e.actionButtonHeader}),t(l,{style:[e.actionLabel,d&&e.actionLabelDesktop],children:"Copy"})]}),i(n,{style:[e.actionWrapper,d&&e.actionWrapperDesktop],children:[t(C,{style:[e.iconButton,d&&e.iconButtonDesktop,x&&e.refreshButtonDisabled],onPress:ie,disabled:x,testID:"buoy-routes-sitemap-refresh",accessibilityRole:"button",accessibilityLabel:"Refresh route tree",children:t(Se,{size:F,color:x?o.color.textTertiary:o.color.textSecondary})}),t(l,{style:[e.actionLabel,d&&e.actionLabelDesktop],children:"Refresh"})]}),i(n,{style:[e.actionWrapper,d&&e.actionWrapperDesktop],children:[t(C,{style:[e.iconButton,d&&e.iconButtonDesktop],onPress:()=>h(true),testID:"buoy-routes-sitemap-search-open",accessibilityRole:"button",accessibilityLabel:"Search routes",children:t(q,{size:F,color:o.color.textSecondary})}),t(l,{style:[e.actionLabel,d&&e.actionLabelDesktop],children:"Search"})]})]}),i(n,{style:e.statsGrid,children:[t(R,{value:u.total,label:"Total",id:"total"}),t(R,{value:u.static,label:"Static",id:"static"}),t(R,{value:u.dynamic,label:"Dynamic",id:"dynamic"}),t(R,{value:u.catchAll,label:"Catch-All",id:"catch-all"}),t(R,{value:u.layouts,label:"Layouts",id:"layouts"}),t(R,{value:u.groups,label:"Groups",id:"groups"})]})]}),Q.length===0?t(pe,{testID:"buoy-routes-sitemap-empty",otto:"map",title:"No routes found",message:"Nothing in the router matches. Clear the search to see the whole tree."}):Q.map(a=>t(we,{group:a,isExpanded:p.length>0||v.has(a.title),onToggleExpand:()=>ae(a.title),onNavigate:A},a.title)),i(n,{style:e.metaFooter,children:[t(l,{style:e.metaText,testID:"buoy-routes-sitemap-updated",children:le}),t(n,{style:e.sourceBadge,children:t(l,{style:e.sourceText,testID:"buoy-routes-sitemap-source",children:se})})]})]}),t(Ie,{visible:P,onClose:()=>V(false),featureName:"Route Navigation"})]})}function R({value:r,label:g,id:f}){return i(n,{style:e.statItem,testID:`buoy-routes-stat-${f}`,accessibilityLabel:`${g}, ${r}`,children:[t(l,{style:e.statValue,testID:`buoy-routes-stat-${f}-value`,children:r}),t(l,{style:e.statLabel,children:g})]})}function we({group:r,isExpanded:g,onToggleExpand:f,onNavigate:S}){return i(n,{style:e.groupContainer,children:[i(C,{style:e.groupHeader,onPress:f,activeOpacity:.7,testID:Y(r.title),accessibilityRole:"button",accessibilityLabel:`${r.title}, ${r.routes.length} routes`,children:[i(n,{style:e.groupHeaderLeft,children:[g?t(J,{size:14,color:o.color.textSecondary}):t(X,{size:14,color:o.color.textSecondary}),t(l,{style:e.groupTitle,children:r.title})]}),t(n,{style:e.groupBadge,children:t(l,{style:e.groupCount,testID:`${Y(r.title)}-count`,children:r.routes.length})})]}),r.description&&t(n,{style:e.groupDescription,children:t(l,{style:e.groupDescriptionText,children:r.description})}),g&&t(n,{style:e.routesList,children:r.routes.map((b,p)=>t(ee,{route:b,onNavigate:S},`${b.path}-${p}`))})]})}function ee({route:r,depth:g=0,onNavigate:f}){const[S,b]=B(false);const p=r.children.length>0;const D=ze(r.type);const z=r.type!=="layout"&&r.type!=="group";const h=Re(r.path);const v=p;const E=v?S:true;return t(n,{style:[e.routeItem,{marginLeft:g*12}],testID:h,children:i(n,{style:e.routeCard,children:[i(n,{style:e.routeHeader,children:[v?i(C,{style:e.routeHeaderLeft,onPress:()=>b(!S),activeOpacity:.7,testID:`${h}-toggle`,accessibilityRole:"button",accessibilityLabel:`${r.path}, ${r.type}, ${r.children.length} nested`,children:[t(n,{style:e.expandIndicator,children:S?t(J,{size:14,color:o.color.textSecondary}):t(X,{size:14,color:o.color.textSecondary})}),t(l,{style:e.routePath,numberOfLines:3,testID:`${h}-path`,children:r.path})]}):i(n,{style:e.routeHeaderLeft,accessible:true,accessibilityLabel:`${r.path}, ${r.type}`,children:[t(n,{style:e.expandIndicator}),t(l,{style:e.routePath,numberOfLines:3,testID:`${h}-path`,children:r.path})]}),i(n,{style:e.routeHeaderActions,children:[p&&t(n,{style:e.childCountBadge,children:t(l,{style:e.childCountText,testID:`${h}-children-count`,children:r.children.length})}),t(n,{style:[e.typeTag,{backgroundColor:`${D}15`,borderColor:`${D}40`}],children:t(l,{style:[e.typeText,{color:D}],testID:`${h}-type`,children:r.type.toUpperCase()})}),t(xe,{value:r.path,buttonStyle:e.iconAction,testID:`${h}-copy`}),z&&t(C,{style:e.goButton,onPress:()=>f(r),activeOpacity:.7,testID:`${h}-go`,accessibilityRole:"button",accessibilityLabel:`Go to ${r.path}`,children:t(l,{style:e.goButtonText,children:"Go"})})]})]}),E&&p&&t(n,{style:e.childrenContainer,children:r.children.map((x,W)=>t(ee,{route:x,depth:g+1,onNavigate:f},`${x.path}-${W}`))})]})})}function ze(r){switch(r){case"static":return"#3B82F6";case"dynamic":return"#F59E0B";case"catch-all":return"#EC4899";case"index":return"#10B981";case"layout":return"#8B5CF6";case"group":return"#6366F1";case"not-found":return"#EF4444";default:return"#6B7280"}}const e=ye.create({container:{flex:1,backgroundColor:"transparent"},loadingContainer:{flex:1,justifyContent:"center",alignItems:"center"},loadingText:{color:o.color.textSecondary,fontSize:14,fontFamily:c,textAlign:"center",lineHeight:20,paddingHorizontal:32,maxWidth:420},header:{flexDirection:"column",padding:8,borderBottomWidth:1,borderBottomColor:o.color.border,gap:12,marginBottom:8},actionsRow:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",gap:12,paddingBottom:4},statsGrid:{flexDirection:"row",flexWrap:"wrap",gap:8},statItem:{flexGrow:1,flexShrink:1,flexBasis:"30%",minWidth:90,backgroundColor:o.color.surface,borderRadius:8,paddingVertical:10,paddingHorizontal:12,alignItems:"center"},statValue:{fontSize:18,fontWeight:"800",color:o.color.text,fontFamily:c},statLabel:{fontSize:10,color:o.color.textTertiary,marginTop:4,fontFamily:c,textTransform:"uppercase",letterSpacing:.5},actionWrapper:{flex:1,alignItems:"center",justifyContent:"center",gap:4,minWidth:48},actionWrapperDesktop:{gap:8,minWidth:72},actionButtonHeader:{padding:6,borderRadius:4,backgroundColor:o.color.surfaceElevated},actionButtonHeaderDesktop:{padding:12,borderRadius:8,backgroundColor:o.color.surfaceElevated},iconButton:{padding:6,borderRadius:4,alignItems:"center",justifyContent:"center"},iconButtonDesktop:{padding:12,borderRadius:8,backgroundColor:o.color.surfaceElevated},actionLabel:{fontSize:8,color:o.color.textTertiary,fontFamily:c,textTransform:"uppercase",letterSpacing:.5},actionLabelDesktop:{fontSize:12},refreshButtonDisabled:{opacity:.5},metaFooter:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",gap:8,paddingHorizontal:16,paddingVertical:16,marginTop:16,borderTopWidth:1,borderTopColor:o.color.border},metaText:{fontSize:12,color:o.color.textSecondary,fontFamily:c},sourceBadge:{paddingHorizontal:8,paddingVertical:2,borderRadius:999,borderWidth:1,borderColor:o.color.border,backgroundColor:o.color.surface},sourceText:{fontSize:11,color:o.color.textSecondary,textTransform:"capitalize",fontFamily:c},searchContainer:{flexDirection:"row",alignItems:"center",padding:8,gap:8,borderBottomWidth:1,borderBottomColor:o.color.border},searchInput:{flex:1,color:o.color.text,fontSize:14,fontFamily:c},clearButton:{padding:4},clearButtonText:{color:o.color.textTertiary,fontSize:18},closeSearchButton:{paddingHorizontal:8,paddingVertical:4},closeSearchText:{color:o.color.accent,fontSize:14,fontWeight:"600",fontFamily:c},scrollView:{flex:1},scrollContent:{paddingBottom:8},emptyState:{padding:32,alignItems:"center"},emptyText:{color:o.color.textSecondary,fontSize:14,fontFamily:c},groupContainer:{marginVertical:4},groupHeader:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",padding:12,paddingHorizontal:16,backgroundColor:o.color.surface,borderLeftWidth:3,borderLeftColor:o.color.fillTertiary},groupHeaderLeft:{flexDirection:"row",alignItems:"center",gap:8,flex:1},groupTitle:{fontSize:12,fontWeight:"700",color:o.color.text,fontFamily:c,textTransform:"uppercase",letterSpacing:.8},groupBadge:{backgroundColor:"#3B82F615",borderColor:"#3B82F640",borderWidth:1,borderRadius:12,paddingHorizontal:8,paddingVertical:3,minWidth:24,alignItems:"center",justifyContent:"center"},groupCount:{fontSize:11,fontWeight:"600",color:"#3B82F6",fontFamily:c},routesList:{backgroundColor:"transparent"},groupDescription:{paddingHorizontal:16,paddingVertical:8,marginBottom:8,backgroundColor:o.color.surfaceElevated,borderLeftWidth:3,borderLeftColor:o.color.fillTertiary},groupDescriptionText:{fontSize:11,color:o.color.textSecondary,fontFamily:c,lineHeight:16},routeItem:{marginBottom:6},routeCard:{backgroundColor:o.color.surface,borderRadius:6,borderWidth:1,borderColor:o.color.border,overflow:"hidden",shadowColor:"#000",shadowOffset:{width:0,height:1},shadowOpacity:.05,shadowRadius:2,elevation:1},routeHeader:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",paddingVertical:7,paddingHorizontal:10,gap:8},expandIndicator:{width:18,alignItems:"center"},routeHeaderLeft:{flexDirection:"row",alignItems:"center",gap:8,flex:1},routePath:{fontSize:13,fontWeight:"600",color:o.color.text,fontFamily:c,flex:1},routeHeaderActions:{flexDirection:"row",alignItems:"center",gap:6},childCountBadge:{backgroundColor:"#6B728015",borderColor:"#6B728040",borderWidth:1,borderRadius:12,paddingHorizontal:7,paddingVertical:2,minWidth:22,alignItems:"center",justifyContent:"center"},childCountText:{fontSize:11,fontWeight:"600",color:o.color.textSecondary,fontFamily:c},typeTag:{borderRadius:4,paddingHorizontal:6,paddingVertical:2,borderWidth:1},typeText:{fontSize:10,fontWeight:"600",fontFamily:c},iconAction:{width:28,height:24,borderRadius:4,backgroundColor:o.color.surfaceElevated,borderWidth:1,borderColor:o.color.border,alignItems:"center",justifyContent:"center"},goButton:{height:24,paddingHorizontal:10,borderRadius:4,alignItems:"center",justifyContent:"center",backgroundColor:o.color.accentSoft,borderWidth:1,borderColor:o.color.accentBorder},goButtonText:{fontSize:12,color:o.color.accent,fontFamily:c,fontWeight:"600"},childrenContainer:{borderLeftWidth:2,borderLeftColor:o.color.border,marginLeft:16,marginRight:8,marginTop:2,marginBottom:8}});
|
|
3
|
+
Route: ${a.path}`;const ue=c=>{if(c&&c.trim()){H(a,s+1,{...y,[F]:c.trim()})}};if(typeof S.prompt!=="function"){const c=globalThis.prompt;if(c)ue(c(`${_}
|
|
4
|
+
|
|
5
|
+
${J}`));else S.alert(_,`${a.path} needs a value for ${q}, and this platform can't ask for one here.`);return}S.prompt(_,J,[{text:"Cancel",style:"cancel"},{text:s<M.length-1?"Next":"Navigate",onPress:c=>{if(c&&c.trim()){const T={...y,[F]:c.trim()};H(a,s+1,T)}else{S.alert("Invalid Value","Please enter a value for the parameter")}}}],"plain-text")},[L]);const U=w((a,s)=>{if(b){b(a);return}if(!v&&!s?.bypassPro){O(true);return}if(a.type==="layout"||a.type==="group"){S.alert("Cannot Navigate",`${a.type==="layout"?"Layouts":"Route groups"} are not navigable routes`);return}if(a.type==="dynamic"||a.type==="catch-all"){if(a.params.length===0){try{L.push(a.path)}catch(y){S.alert("Navigation Error",String(y))}return}H(a);return}try{L.push(a.path)}catch(y){S.alert("Navigation Error",String(y))}},[L,H,v,b]);const se=w(()=>{U($e,{bypassPro:true})},[U]);const ce=w(()=>{if(x)return;W(true);Q();setTimeout(()=>W(false),400)},[x,Q]);const de=E(()=>{if(!G)return"Awaiting route data";return`Updated ${Be(G)}`},[G]);const pe=E(()=>{if(!A)return"Source: unknown";return`Source: ${A}`},[A]);const Z=E(()=>{if(u&&N.length>0){return[{title:"Search Results",icon:"",routes:N}]}return k},[u,N,k]);if(!ae){return t(n,{style:[e.container,r],children:t(n,{style:e.loadingContainer,children:t(l,{style:e.loadingText,testID:"buoy-routes-sitemap-loading",children:ne?"Loading routes...":"Route sitemap isn't available on the dashboard \u2014 the route tree lives on the device. Use the Events tab to see navigation here."})})})}return i(n,{style:[e.container,r],children:[z&&i(n,{style:e.searchContainer,testID:"buoy-routes-sitemap-search-field",children:[t(Y,{size:16,color:o.color.textTertiary}),t(ge,{style:e.searchInput,placeholder:"Search routes...",placeholderTextColor:o.color.placeholder,value:u,onChangeText:I,autoCapitalize:"none",autoCorrect:false,autoFocus:true,testID:"buoy-routes-sitemap-search",accessibilityLabel:"Search routes"}),u.length>0&&t(C,{onPress:()=>I(""),style:e.clearButton,testID:"buoy-routes-sitemap-search-clear",accessibilityRole:"button",accessibilityLabel:"Clear route search",children:t(l,{style:e.clearButtonText,children:"\u2715"})}),t(C,{style:e.closeSearchButton,onPress:()=>{g(false);I("")},testID:"buoy-routes-sitemap-search-done",accessibilityRole:"button",accessibilityLabel:"Done searching routes",children:t(l,{style:e.closeSearchText,children:"Done"})})]}),i(fe,{testID:"buoy-routes-sitemap-scroll",style:e.scrollView,contentContainerStyle:e.scrollContent,children:[!z&&i(n,{style:e.header,children:[i(n,{style:e.actionsRow,children:[i(n,{style:[e.actionWrapper,p&&e.actionWrapperDesktop],children:[t(C,{style:[e.iconButton,p&&e.iconButtonDesktop],onPress:se,accessibilityLabel:"Go to home route",accessibilityRole:"button",testID:"buoy-routes-sitemap-home",children:t(Se,{size:P,color:o.color.textSecondary})}),t(l,{style:[e.actionLabel,p&&e.actionLabelDesktop],children:"Home"})]}),i(n,{style:[e.actionWrapper,p&&e.actionWrapperDesktop],children:[t(Ie,{value:ie,testID:"buoy-routes-sitemap-copy",size:p?P:14,buttonStyle:p?e.actionButtonHeaderDesktop:e.actionButtonHeader}),t(l,{style:[e.actionLabel,p&&e.actionLabelDesktop],children:"Copy"})]}),i(n,{style:[e.actionWrapper,p&&e.actionWrapperDesktop],children:[t(C,{style:[e.iconButton,p&&e.iconButtonDesktop,x&&e.refreshButtonDisabled],onPress:ce,disabled:x,testID:"buoy-routes-sitemap-refresh",accessibilityRole:"button",accessibilityLabel:"Refresh route tree",children:t(Te,{size:P,color:x?o.color.textTertiary:o.color.textSecondary})}),t(l,{style:[e.actionLabel,p&&e.actionLabelDesktop],children:"Refresh"})]}),i(n,{style:[e.actionWrapper,p&&e.actionWrapperDesktop],children:[t(C,{style:[e.iconButton,p&&e.iconButtonDesktop],onPress:()=>g(true),testID:"buoy-routes-sitemap-search-open",accessibilityRole:"button",accessibilityLabel:"Search routes",children:t(Y,{size:P,color:o.color.textSecondary})}),t(l,{style:[e.actionLabel,p&&e.actionLabelDesktop],children:"Search"})]})]}),i(n,{style:e.statsGrid,children:[t(R,{value:h.total,label:"Total",id:"total"}),t(R,{value:h.static,label:"Static",id:"static"}),t(R,{value:h.dynamic,label:"Dynamic",id:"dynamic"}),t(R,{value:h.catchAll,label:"Catch-All",id:"catch-all"}),t(R,{value:h.layouts,label:"Layouts",id:"layouts"}),t(R,{value:h.groups,label:"Groups",id:"groups"})]})]}),Z.length===0?t(ye,{testID:"buoy-routes-sitemap-empty",otto:"map",title:"No routes found",message:"Nothing in the router matches. Clear the search to see the whole tree."}):Z.map(a=>t(We,{group:a,isExpanded:u.length>0||$.has(a.title),onToggleExpand:()=>le(a.title),onNavigate:U},a.title)),i(n,{style:e.metaFooter,children:[t(l,{style:e.metaText,testID:"buoy-routes-sitemap-updated",children:de}),t(n,{style:e.sourceBadge,children:t(l,{style:e.sourceText,testID:"buoy-routes-sitemap-source",children:pe})})]})]}),t(Re,{visible:j,onClose:()=>O(false),featureName:"Route Navigation"})]})}function R({value:r,label:f,id:m}){return i(n,{style:e.statItem,testID:`buoy-routes-stat-${m}`,accessibilityLabel:`${f}, ${r}`,children:[t(l,{style:e.statValue,testID:`buoy-routes-stat-${m}-value`,children:r}),t(l,{style:e.statLabel,children:f})]})}function We({group:r,isExpanded:f,onToggleExpand:m,onNavigate:D}){return i(n,{style:e.groupContainer,children:[i(C,{style:e.groupHeader,onPress:m,activeOpacity:.7,testID:oe(r.title),accessibilityRole:"button",accessibilityLabel:`${r.title}, ${r.routes.length} routes`,children:[i(n,{style:e.groupHeaderLeft,children:[f?t(ee,{size:14,color:o.color.textSecondary}):t(te,{size:14,color:o.color.textSecondary}),t(l,{style:e.groupTitle,children:r.title})]}),t(n,{style:e.groupBadge,children:t(l,{style:e.groupCount,testID:`${oe(r.title)}-count`,children:r.routes.length})})]}),r.description&&t(n,{style:e.groupDescription,children:t(l,{style:e.groupDescriptionText,children:r.description})}),f&&t(n,{style:e.routesList,children:r.routes.map((b,u)=>t(re,{route:b,onNavigate:D},`${b.path}-${u}`))})]})}function re({route:r,depth:f=0,onNavigate:m}){const[D,b]=B(false);const u=r.children.length>0;const I=ve(r.type);const z=r.type!=="layout"&&r.type!=="group";const g=ze(r.path);const $=u;const V=$?D:true;return t(n,{style:[e.routeItem,{marginLeft:f*12}],testID:g,children:i(n,{style:e.routeCard,children:[i(n,{style:e.routeHeader,children:[$?i(C,{style:e.routeHeaderLeft,onPress:()=>b(!D),activeOpacity:.7,testID:`${g}-toggle`,accessibilityRole:"button",accessibilityLabel:`${r.path}, ${r.type}, ${r.children.length} nested`,children:[t(n,{style:e.expandIndicator,children:D?t(ee,{size:14,color:o.color.textSecondary}):t(te,{size:14,color:o.color.textSecondary})}),t(l,{style:e.routePath,numberOfLines:3,testID:`${g}-path`,children:r.path})]}):i(n,{style:e.routeHeaderLeft,accessible:true,accessibilityLabel:`${r.path}, ${r.type}`,children:[t(n,{style:e.expandIndicator}),t(l,{style:e.routePath,numberOfLines:3,testID:`${g}-path`,children:r.path})]}),i(n,{style:e.routeHeaderActions,children:[u&&t(n,{style:e.childCountBadge,children:t(l,{style:e.childCountText,testID:`${g}-children-count`,children:r.children.length})}),t(n,{style:[e.typeTag,{backgroundColor:`${I}15`,borderColor:`${I}40`}],children:t(l,{style:[e.typeText,{color:I}],testID:`${g}-type`,children:r.type.toUpperCase()})}),t(De,{value:r.path,buttonStyle:e.iconAction,testID:`${g}-copy`}),z&&t(C,{style:e.goButton,onPress:()=>m(r),activeOpacity:.7,testID:`${g}-go`,accessibilityRole:"button",accessibilityLabel:`Go to ${r.path}`,children:t(l,{style:e.goButtonText,children:"Go"})})]})]}),V&&u&&t(n,{style:e.childrenContainer,children:r.children.map((x,W)=>t(re,{route:x,depth:f+1,onNavigate:m},`${x.path}-${W}`))})]})})}function ve(r){switch(r){case"static":return"#3B82F6";case"dynamic":return"#F59E0B";case"catch-all":return"#EC4899";case"index":return"#10B981";case"layout":return"#8B5CF6";case"group":return"#6366F1";case"not-found":return"#EF4444";default:return"#6B7280"}}const e=me.create({container:{flex:1,backgroundColor:"transparent"},loadingContainer:{flex:1,justifyContent:"center",alignItems:"center"},loadingText:{color:o.color.textSecondary,fontSize:14,fontFamily:d,textAlign:"center",lineHeight:20,paddingHorizontal:32,maxWidth:420},header:{flexDirection:"column",padding:8,borderBottomWidth:1,borderBottomColor:o.color.border,gap:12,marginBottom:8},actionsRow:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",gap:12,paddingBottom:4},statsGrid:{flexDirection:"row",flexWrap:"wrap",gap:8},statItem:{flexGrow:1,flexShrink:1,flexBasis:"30%",minWidth:90,backgroundColor:o.color.surface,borderRadius:8,paddingVertical:10,paddingHorizontal:12,alignItems:"center"},statValue:{fontSize:18,fontWeight:"800",color:o.color.text,fontFamily:d},statLabel:{fontSize:10,color:o.color.textTertiary,marginTop:4,fontFamily:d,textTransform:"uppercase",letterSpacing:.5},actionWrapper:{flex:1,alignItems:"center",justifyContent:"center",gap:4,minWidth:48},actionWrapperDesktop:{gap:8,minWidth:72},actionButtonHeader:{padding:6,borderRadius:4,backgroundColor:o.color.surfaceElevated},actionButtonHeaderDesktop:{padding:12,borderRadius:8,backgroundColor:o.color.surfaceElevated},iconButton:{padding:6,borderRadius:4,alignItems:"center",justifyContent:"center"},iconButtonDesktop:{padding:12,borderRadius:8,backgroundColor:o.color.surfaceElevated},actionLabel:{fontSize:8,color:o.color.textTertiary,fontFamily:d,textTransform:"uppercase",letterSpacing:.5},actionLabelDesktop:{fontSize:12},refreshButtonDisabled:{opacity:.5},metaFooter:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",gap:8,paddingHorizontal:16,paddingVertical:16,marginTop:16,borderTopWidth:1,borderTopColor:o.color.border},metaText:{fontSize:12,color:o.color.textSecondary,fontFamily:d},sourceBadge:{paddingHorizontal:8,paddingVertical:2,borderRadius:999,borderWidth:1,borderColor:o.color.border,backgroundColor:o.color.surface},sourceText:{fontSize:11,color:o.color.textSecondary,textTransform:"capitalize",fontFamily:d},searchContainer:{flexDirection:"row",alignItems:"center",padding:8,gap:8,borderBottomWidth:1,borderBottomColor:o.color.border},searchInput:{flex:1,color:o.color.text,fontSize:14,fontFamily:d},clearButton:{padding:4},clearButtonText:{color:o.color.textTertiary,fontSize:18},closeSearchButton:{paddingHorizontal:8,paddingVertical:4},closeSearchText:{color:o.color.accent,fontSize:14,fontWeight:"600",fontFamily:d},scrollView:{flex:1},scrollContent:{paddingBottom:8},emptyState:{padding:32,alignItems:"center"},emptyText:{color:o.color.textSecondary,fontSize:14,fontFamily:d},groupContainer:{marginVertical:4},groupHeader:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",padding:12,paddingHorizontal:16,backgroundColor:o.color.surface,borderLeftWidth:3,borderLeftColor:o.color.fillTertiary},groupHeaderLeft:{flexDirection:"row",alignItems:"center",gap:8,flex:1},groupTitle:{fontSize:12,fontWeight:"700",color:o.color.text,fontFamily:d,textTransform:"uppercase",letterSpacing:.8},groupBadge:{backgroundColor:"#3B82F615",borderColor:"#3B82F640",borderWidth:1,borderRadius:12,paddingHorizontal:8,paddingVertical:3,minWidth:24,alignItems:"center",justifyContent:"center"},groupCount:{fontSize:11,fontWeight:"600",color:"#3B82F6",fontFamily:d},routesList:{backgroundColor:"transparent"},groupDescription:{paddingHorizontal:16,paddingVertical:8,marginBottom:8,backgroundColor:o.color.surfaceElevated,borderLeftWidth:3,borderLeftColor:o.color.fillTertiary},groupDescriptionText:{fontSize:11,color:o.color.textSecondary,fontFamily:d,lineHeight:16},routeItem:{marginBottom:6},routeCard:{backgroundColor:o.color.surface,borderRadius:6,borderWidth:1,borderColor:o.color.border,overflow:"hidden",shadowColor:"#000",shadowOffset:{width:0,height:1},shadowOpacity:.05,shadowRadius:2,elevation:1},routeHeader:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",paddingVertical:7,paddingHorizontal:10,gap:8},expandIndicator:{width:18,alignItems:"center"},routeHeaderLeft:{flexDirection:"row",alignItems:"center",gap:8,flex:1},routePath:{fontSize:13,fontWeight:"600",color:o.color.text,fontFamily:d,flex:1},routeHeaderActions:{flexDirection:"row",alignItems:"center",gap:6},childCountBadge:{backgroundColor:"#6B728015",borderColor:"#6B728040",borderWidth:1,borderRadius:12,paddingHorizontal:7,paddingVertical:2,minWidth:22,alignItems:"center",justifyContent:"center"},childCountText:{fontSize:11,fontWeight:"600",color:o.color.textSecondary,fontFamily:d},typeTag:{borderRadius:4,paddingHorizontal:6,paddingVertical:2,borderWidth:1},typeText:{fontSize:10,fontWeight:"600",fontFamily:d},iconAction:{width:28,height:24,borderRadius:4,backgroundColor:o.color.surfaceElevated,borderWidth:1,borderColor:o.color.border,alignItems:"center",justifyContent:"center"},goButton:{height:24,paddingHorizontal:10,borderRadius:4,alignItems:"center",justifyContent:"center",backgroundColor:o.color.accentSoft,borderWidth:1,borderColor:o.color.accentBorder},goButtonText:{fontSize:12,color:o.color.accent,fontFamily:d,fontWeight:"600"},childrenContainer:{borderLeftWidth:2,borderLeftColor:o.color.border,marginLeft:16,marginRight:8,marginTop:2,marginBottom:8}});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";let o=null;let l=null;let u=null;let n=false;let s=false;let i=null;function a(e,r){if(__DEV__){if(r){console.error(
|
|
1
|
+
"use strict";let o=null;let l=null;let u=null;let n=false;let s=false;let i=null;function a(e,r){if(__DEV__){if(r){console.error("[Buoy]",`[RouteEvents] ${e}`,r)}else{console.warn("[Buoy]",`[RouteEvents] ${e}`)}}}export function isExpoRouterStoreSupported(){return typeof require!=="undefined"}export function getExpoRouterStore(){if(o){return o}if(!isExpoRouterStoreSupported()){return null}const e=()=>{try{const t=require("expo-router/build/global-state/router-store");if(t?.store){o=t.store;l="build";u=null;n=false;return true}}catch(t){u=t}return false};const r=()=>{try{const t=require("expo-router/src/global-state/router-store");if(t?.store){o=t.store;l="src";u=null;n=false;return true}}catch(t){u=t}return false};if(e()||r()){return o}if(!n){a("Unable to load expo-router internals. @buoy-gg/route-events requires expo-router >= 2.0.0. Install expo-router and ensure it is configured before using the Routes tab.",u??void 0);n=true}return null}export function loadRouteNode(){const e=getExpoRouterStore();if(!e){return null}if(e.routeNode){s=false;i=Date.now();return e.routeNode}const r=e.navigationRef?.isReady?.();if(__DEV__&&!s&&r){a("Expo Router route tree is unavailable. Ensure your app directory is configured and that expo-router is initialized before opening the Route Events devtool.");s=true}return null}export function getRouteNodeMetadata(){return{source:l,lastLoadedAt:i}}export function isRouteListComplete(){return true}
|
package/lib/module/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";export{routeEventsToolPreset,createRouteEventsTool}from"./preset";export{RouteEventsModalWithTabs,RoutesToolView}from"./components/RouteEventsModalWithTabs";export{RouteTracker}from"./RouteTracker";export{registerBrowserRoutes}from"./browserRouteRegistry";export{RoutesSitemap}from"./components/RoutesSitemap";export{NavigationStack}from"./components/NavigationStack";export{RouteEventItemCompact}from"./components/RouteEventItemCompact";export{RouteEventExpandedContent}from"./components/RouteEventExpandedContent";export{RouteEventDetail}from"./components/RouteEventDetail";export{useRouteObserver}from"./useRouteObserver";export{useRouteObserverReactNavigation}from"./useRouteObserverReactNavigation";export{useRouteEvents}from"./hooks/useRouteEvents";export{useRouteSitemap,useRoute,useParentRoutes}from"./useRouteSitemap";export{useNavigationStack}from"./useNavigationStack";export{routeEventsSyncAdapter}from"./sync/routeEventsSyncAdapter";export{RouteParser}from"./RouteParser";export{RouteObserver}from"./RouteObserver";export{routeObserver}from"./RouteObserver";export{routeEventStore}from"./stores/routeEventStore";export{navigationStackStore}from"./stores/navigationStackStore";
|
|
1
|
+
"use strict";export{routeEventsToolPreset,createRouteEventsTool}from"./preset";export{RouteEventsModalWithTabs,RoutesToolView}from"./components/RouteEventsModalWithTabs";export{RouteTracker}from"./RouteTracker";export{registerBrowserRoutes,claimBrowserRouteEvents}from"./browserRouteRegistry";export{RoutesSitemap}from"./components/RoutesSitemap";export{NavigationStack}from"./components/NavigationStack";export{RouteEventItemCompact}from"./components/RouteEventItemCompact";export{RouteEventExpandedContent}from"./components/RouteEventExpandedContent";export{RouteEventDetail}from"./components/RouteEventDetail";export{useRouteObserver}from"./useRouteObserver";export{useRouteObserverReactNavigation}from"./useRouteObserverReactNavigation";export{useRouteEvents}from"./hooks/useRouteEvents";export{useRouteSitemap,useRoute,useParentRoutes}from"./useRouteSitemap";export{useNavigationStack}from"./useNavigationStack";export{routeEventsSyncAdapter}from"./sync/routeEventsSyncAdapter";export{RouteParser}from"./RouteParser";export{RouteObserver}from"./RouteObserver";export{routeObserver}from"./RouteObserver";export{routeEventStore}from"./stores/routeEventStore";export{navigationStackStore}from"./stores/navigationStackStore";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{useState as I,useEffect as
|
|
1
|
+
"use strict";import{useState as I,useEffect as $,useMemo as N,useCallback as R}from"react";import{getCommonActions as L,getStackActions as W,useSafeNavigationContainerRef as j}from"./utils/safeReactNavigation";import{getSafeRouter as b,isExpoRouterAvailable as w}from"@buoy-gg/shared-ui";const F=L();const C=W();function B(e,t){if(!e||!e.routes)return null;for(const n of e.routes){if(n.name===t){return[n.name]}if(n.state){const l=B(n.state,t);if(l){return[n.name,...l]}}}return null}function E(e){if(e.length===0)return null;if(e.length===1){return F.navigate({name:e[0]})}let t={screen:e[e.length-1]};for(let n=e.length-2;n>=1;n--){t={screen:e[n],params:t}}return F.navigate({name:e[0],params:t})}function _(e,t=0,n="",l=true){if(!e||!Array.isArray(e.routes)||e.routes.length===0){return[]}const g=[];const d=typeof e.index==="number"?e.index:NaN;const y=Number.isInteger(d)&&d>=0&&d<e.routes.length?d:e.routes.length-1;const a=typeof e.type==="string"?e.type:void 0;const r=a!=="tab"&&a!=="drawer";for(let i=0;i<e.routes.length;i++){if(!r&&i!==y)continue;const c=e.routes[i];const h=i===y;let u=c.name;if(c.name==="index"){u="/"}else if(!u.startsWith("/")){u=`/${u}`}if(n&&n!=="/"){u=`${n}${u}`}if(c.params){const S=Object.entries(c.params);if(S.length>0){u=u.replace(/\[([^\]]+)\]/g,(x,A)=>{return c.params[A]||x})}}const k=l&&h;const v=k&&c.state?_(c.state,t+1,u,true):[];g.push({key:c.key,name:c.name,path:u,params:c.params||{},state:c.state,isFocused:k&&v.length===0});g.push(...v)}return g}export function buildStack(e,t){if(!e)return[];try{const n=_(e);const l=t?n.filter(a=>{if(a.name.startsWith("__"))return false;if(a.name.includes("_layout"))return false;if(a.name.startsWith("+not-found"))return false;return true}):n;const g=l.length>0?l:n.slice(-1);const d=g.findIndex(a=>a.isFocused);const y=d>=0?d:g.length-1;return g.map((a,r)=>{let i=a.path||`/${a.name}`;if(t){i=i.replace(/^\/__root/,"")}if(!i||i===""){i="/"}return{key:a.key,name:a.name,pathname:i,params:a.params||{},isFocused:r===y,index:r,canPop:r>0}})}catch(n){console.error("[Buoy]","Error transforming navigation state:",n);return[]}}export function useNavigationStack(){const e=w();const t=j();const[n,l]=I(()=>t?.getRootState?.()??null);const[g,d]=I(false);const[y,a]=I(null);$(()=>{if(!t)return;const o=t.getRootState?.();if(o){l(o)}d(true);const f=t.addListener?.("state",()=>{const s=t.getRootState?.();if(s){l(s)}});return()=>{f?.()}},[t]);const r=N(()=>buildStack(n,e),[n,e]);const i=N(()=>{return r.find(o=>o.isFocused)||null},[r]);const c=r.length;const h=c<=1;const u=R(()=>{if(!t)return;const o=t.getRootState?.();if(o){l(o)}},[t]);const k=R(o=>{if(o>=r.length||o<0)return;const f=r[o];if(!f)return;try{const s=b();if(s){s.navigate(f.pathname)}else if(t){const p=t.getRootState?.();if(p){const m=B(p,f.name);if(m){const T=E(m);if(T){t.dispatch(T);return}}}t.dispatch(F.navigate({name:f.name,params:f.params}))}}catch(s){console.error("[Buoy]","Failed to navigate:",s)}},[r,t]);const v=R((o,f)=>{if(!t)return false;try{const s=t.getRootState?.();if(!f&&s){const p=B(s,o);if(p){const m=E(p);if(m){t.dispatch(m);return true}}}t.dispatch(F.navigate({name:o,params:f}));return true}catch(s){console.error("[Buoy]","Failed to navigate:",s);return false}},[t]);const S=R(o=>{if(o>=r.length||o<0)return;const f=r.length-1;const s=f-o;if(s<=0)return;try{const p=b();if(p){for(let m=0;m<s;m++){p.back()}}else if(t){t.dispatch(C.pop(s))}}catch(p){console.error("[Buoy]","Failed to pop:",p)}},[r,t]);const x=R(()=>{if(h)return;try{const o=b();if(o){o.back()}else if(t){t.goBack()}}catch(o){console.error("[Buoy]","Failed to go back:",o)}},[h,t]);const A=R(()=>{if(h)return;try{const o=b();if(o){S(0)}else if(t){t.dispatch(C.popToTop())}}catch(o){console.error("[Buoy]","Failed to pop to top:",o)}},[h,t,S]);return{stack:r,focusedRoute:i,stackDepth:c,isAtRoot:h,isLoaded:g,error:y,refresh:u,navigateToIndex:k,navigateToRoute:v,popToIndex:S,goBack:x,popToTop:A}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{createContext as p,useContext as l,useMemo as c}from"react";let t=null;let a=false;let s=false;let
|
|
1
|
+
"use strict";import{createContext as p,useContext as l,useMemo as c}from"react";let t=null;let a=false;let s=false;let i=null;let v=false;function f(){if(v)return i;v=true;try{const e=require("expo-router/react-navigation");i=e?.NavigationContainerRefContext?e:null}catch{i=null}return i}function o(){if(s)return a;try{t=require("@react-navigation/native");a=t!=null}catch(e){a=false;t=null}if(!a){const e=f();if(e){t=e;a=true}}s=true;return a}function d(){return c(()=>({navigate:()=>console.warn("[Buoy]","[route-events] @react-navigation/native not installed: navigate() unavailable"),goBack:()=>console.warn("[Buoy]","[route-events] @react-navigation/native not installed: goBack() unavailable"),canGoBack:()=>false,reset:()=>console.warn("[Buoy]","[route-events] @react-navigation/native not installed: reset() unavailable"),setParams:()=>console.warn("[Buoy]","[route-events] @react-navigation/native not installed: setParams() unavailable"),dispatch:()=>console.warn("[Buoy]","[route-events] @react-navigation/native not installed: dispatch() unavailable"),isFocused:()=>true,addListener:()=>()=>{},removeListener:()=>{},getParent:()=>void 0,getState:()=>void 0,getId:()=>void 0}),[])}function g(e){return c(()=>{const n={key:"default",index:0,routeNames:[],routes:[],type:"stack"};try{return e?e(n):n}catch{return n}},[e])}export function useSafeNavigation(){if(!o()){return d()}try{return t.useNavigation()}catch(e){console.warn("[Buoy]","[route-events] Failed to use @react-navigation/native.useNavigation:",e);return d()}}export function useSafeNavigationState(e){if(!o()){return g(e)}try{return t.useNavigationState(e)}catch(n){console.warn("[Buoy]","[route-events] Failed to use @react-navigation/native.useNavigationState:",n);return g(e)}}const C=p(void 0);export function getCommonActions(){return o()?t.CommonActions:null}export function getStackActions(){return o()?t.StackActions:null}let r=null;let u=null;function y(){if(r==null){r=o()&&t.NavigationContainerRefContext?t.NavigationContainerRefContext:C}if(u==null){const e=f();u=e?.NavigationContainerRefContext??C}return[r,u]}export function useSafeNavigationContainerRef(){const[e,n]=y();const x=l(e);const N=l(n);return x??N}export function isReactNavigationAvailable(){return o()}
|
|
@@ -5,4 +5,6 @@ export declare function getBrowserRouteInfo(pathname: string): {
|
|
|
5
5
|
segments: string[];
|
|
6
6
|
params: Record<string, string | string[]>;
|
|
7
7
|
};
|
|
8
|
+
export declare function claimBrowserRouteEvents(): () => void;
|
|
9
|
+
export declare function hasBrowserRouteEventSource(): boolean;
|
|
8
10
|
//# sourceMappingURL=browserRouteRegistry.d.ts.map
|
|
@@ -10,7 +10,7 @@ export { routeEventsToolPreset, createRouteEventsTool } from "./preset";
|
|
|
10
10
|
export { RouteEventsModalWithTabs, RoutesToolView, } from "./components/RouteEventsModalWithTabs";
|
|
11
11
|
export type { RouteEventsModalWithTabsProps } from "./components/RouteEventsModalWithTabs";
|
|
12
12
|
export { RouteTracker } from "./RouteTracker";
|
|
13
|
-
export { registerBrowserRoutes } from "./browserRouteRegistry";
|
|
13
|
+
export { registerBrowserRoutes, claimBrowserRouteEvents } from "./browserRouteRegistry";
|
|
14
14
|
export { RoutesSitemap } from "./components/RoutesSitemap";
|
|
15
15
|
export type { RoutesSitemapProps } from "./components/RoutesSitemap";
|
|
16
16
|
export { NavigationStack } from "./components/NavigationStack";
|
package/lib/web/index.mjs
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
"use client";var Bt=Object.defineProperty;var So=Object.getOwnPropertyDescriptor;var To=Object.getOwnPropertyNames;var Co=Object.prototype.hasOwnProperty;var wo=(e,t)=>{for(var o in t)Bt(e,o,{get:t[o],enumerable:true})},Dt=(e,t,o,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of To(t))!Co.call(e,a)&&a!==o&&Bt(e,a,{get:()=>t[a],enumerable:!(r=So(t,a))||r.enumerable});return e},Io=(e,t,o)=>(Dt(e,t,"default"),o&&Dt(o,t,"default"));var Bn=(()=>{try{let e=globalThis.Capacitor;if(e&&typeof e.isNativePlatform=="function"&&e.isNativePlatform())return e.DEBUG===true}catch{}return process.env.NODE_ENV!=="production"})();typeof window<"u"&&typeof globalThis.global>"u"&&(globalThis.global=globalThis);import{RoutesIcon as Ro}from"@buoy-gg/floating-tools-core/web";import{useState as Ie,useCallback as ue,useEffect as Et,useRef as ko,useMemo as Re}from"react";var Pt={};wo(Pt,{AccessibilityInfo:()=>Po,ActivityIndicator:()=>Cr,Alert:()=>J,Animated:()=>Lo,AppRegistry:()=>Fo,AppState:()=>zo,Appearance:()=>$o,BackHandler:()=>No,Button:()=>wr,CheckBox:()=>Xo,Clipboard:()=>Ao,DeviceEventEmitter:()=>pr,Dimensions:()=>Wo,Easing:()=>jo,FlatList:()=>Lt,I18nManager:()=>Vo,Image:()=>Yo,ImageBackground:()=>Zo,InteractionManager:()=>Ho,Keyboard:()=>Oo,KeyboardAvoidingView:()=>er,LayoutAnimation:()=>Mo,Linking:()=>Uo,LogBox:()=>dr,Modal:()=>Sr,NativeEventEmitter:()=>Go,NativeModules:()=>Eo,PanResponder:()=>_o,Picker:()=>tr,PixelRatio:()=>Ko,Platform:()=>at,Pressable:()=>xr,ProgressBar:()=>or,RefreshControl:()=>rr,SafeAreaView:()=>ar,ScrollView:()=>Ue,SectionList:()=>nr,Share:()=>Qo,StatusBar:()=>ir,StyleSheet:()=>ve,Switch:()=>Tr,Text:()=>h,TextInput:()=>$t,Touchable:()=>sr,TouchableHighlight:()=>br,TouchableNativeFeedback:()=>lr,TouchableOpacity:()=>V,TouchableWithoutFeedback:()=>vr,UIManager:()=>Jo,Vibration:()=>qo,View:()=>c,VirtualizedList:()=>cr,YellowBox:()=>ur,findNodeHandle:()=>Ir,unstable_createElement:()=>Do,useColorScheme:()=>mr,useLocaleContext:()=>hr,useWindowDimensions:()=>gr});Io(Pt,Bo);import*as Bo from"react-native-web";import{unstable_createElement as Do,NativeModules as Eo,AccessibilityInfo as Po,Animated as Lo,Appearance as $o,AppRegistry as Fo,AppState as zo,BackHandler as No,Clipboard as Ao,Dimensions as Wo,Easing as jo,I18nManager as Vo,Keyboard as Oo,InteractionManager as Ho,LayoutAnimation as Mo,Linking as Uo,NativeEventEmitter as Go,PanResponder as _o,PixelRatio as Ko,Platform as at,Share as Qo,StyleSheet as ve,UIManager as Jo,Vibration as qo,CheckBox as Xo,FlatList as Lt,Image as Yo,ImageBackground as Zo,KeyboardAvoidingView as er,Picker as tr,ProgressBar as or,RefreshControl as rr,SafeAreaView as ar,SectionList as nr,StatusBar as ir,Touchable as sr,TouchableNativeFeedback as lr,VirtualizedList as cr,YellowBox as ur,LogBox as dr,DeviceEventEmitter as pr,useColorScheme as mr,useLocaleContext as hr,useWindowDimensions as gr}from"react-native-web";import*as ee from"react-native-web";import{createElement as fr,forwardRef as yr}from"react";function oe(e){let t=yr((r,a)=>{let{accessibilityState:i,accessibilityValue:n,...u}=r;for(let l of["busy","checked","disabled","expanded","selected"])i?.[l]!==void 0&&u[`aria-${l}`]===void 0&&(u[`aria-${l}`]=i[l]);for(let[l,g]of Object.entries({min:"valuemin",max:"valuemax",now:"valuenow",text:"valuetext"}))n?.[l]!==void 0&&u[`aria-${g}`]===void 0&&(u[`aria-${g}`]=n[l]);return fr(e,{...u,ref:a})}),o=e.State;return o&&Object.assign(t,{State:o}),t.displayName=e.displayName??e.name??"NativeWebView",t}var c=oe(ee.View),h=oe(ee.Text),$t=oe(ee.TextInput),V=oe(ee.TouchableOpacity),br=oe(ee.TouchableHighlight),vr=oe(ee.TouchableWithoutFeedback),xr=oe(ee.Pressable),Ue=oe(ee.ScrollView),Sr=oe(ee.Modal),Tr=oe(ee.Switch),Cr=oe(ee.ActivityIndicator),wr=oe(ee.Button),Ir=ee.findNodeHandle,J={alert(e,t,o,r){if(typeof document>"u")return;let a=document.createElement("dialog");a.dataset.buoyRoot="",a.setAttribute("aria-label",e),a.style.cssText="position:fixed;inset:0;margin:auto;width:min(440px,90vw);padding:24px;border:1px solid #475569;border-radius:14px;background:#17212e;color:#f1f5f9;font:14px system-ui;box-shadow:0 20px 80px #0008;z-index:2147483647";let i=document.createElement("h2");if(i.textContent=e,i.style.cssText="font-size:18px;margin:0 0 12px",a.appendChild(i),t){let g=document.createElement("p");g.textContent=t,g.style.cssText="line-height:1.5;white-space:pre-wrap;margin:0 0 20px",a.appendChild(g)}let n=document.createElement("div");n.style.cssText="display:flex;justify-content:flex-end;flex-wrap:wrap;gap:8px";let u=o?.length?o:[{text:"OK"}],l=()=>{a.close?.(),a.remove()};for(let g of u){let d=document.createElement("button");d.type="button",d.textContent=g.text??"OK",d.style.cssText=`padding:9px 14px;border:1px solid #64748b;border-radius:7px;color:white;background:${g.style==="destructive"?"#a52b38":"#283a4d"};cursor:pointer;font:inherit`,d.onclick=()=>{l(),g.onPress?.()},n.appendChild(d)}a.addEventListener("cancel",g=>{g.preventDefault(),r?.cancelable!==false&&(l(),r?.onDismiss?.())}),a.appendChild(n),document.body.appendChild(a),a.showModal?a.showModal():a.setAttribute("open","")}};import{browserRouter as Fn}from"@buoy-gg/shared-ui/web/utils";function Rr(){return null}import{useSafeRouter as kr,isExpoRouterAvailable as Br,windowDragProps as Dr,ToolEmptyState as Er,resolveListEmptyState as Pr,usePersistedState as nt,monoFont as Ge}from"@buoy-gg/shared-ui/web";import{JsModal as Lr,ModalHeader as ie,TabSelector as $r,formatRelativeTime as Fr,devToolsStorageKeys as $e,Trash2 as zr,Filter as Nr,SearchBar as Ft,ToolbarCopyButton as it,Lock as Ar,ProUpgradeModal as Wr,PowerToggleButton as jr,buoyColors as Vr,night as G,TickProvider as zt,useLimit as Or}from"@buoy-gg/shared-ui/web";import{useIsPro as Hr}from"@buoy-gg/license/web";import{useEventStoreEvents as Mr}from"@buoy-gg/shared-ui/web";import{BaseEventStore as Ur,devToolsStorageKeys as Gr,persistentStorage as _r}from"@buoy-gg/shared-ui/web";var Nt=class{constructor(){this.listeners=new Set}emit(e){this.listeners.forEach(t=>{try{t(e)}catch(o){console.error("[RouteObserver] Error in listener:",o)}})}addListener(e){return this.listeners.add(e),()=>this.listeners.delete(e)}removeListener(e){this.listeners.delete(e)}},Fe=new Nt;var Kr=class extends Ur{constructor(){super({storeName:"route-events",maxEvents:500});this.routeObserverUnsubscribe=null;this.bootCaptureRelease=null;this.bootCaptureHydrated=false}setBootCapture(e){e&&!this.bootCaptureRelease?this.bootCaptureRelease=this.subscribeToEvents(()=>{}):!e&&this.bootCaptureRelease&&(this.bootCaptureRelease(),this.bootCaptureRelease=null)}hydrateBootCapture(){this.bootCaptureHydrated||(this.bootCaptureHydrated=true,_r.getItem(Gr.routeEvents.isMonitoring()).then(e=>{this.bootCaptureRelease||this.setBootCapture(e!=="false")}).catch(()=>this.setBootCapture(true)))}startCapturing(){this.routeObserverUnsubscribe||(this.routeObserverUnsubscribe=Fe.addListener(e=>{this.addEvent(e)}))}stopCapturing(){this.routeObserverUnsubscribe&&(this.routeObserverUnsubscribe(),this.routeObserverUnsubscribe=null)}isCapturing(){return this.routeObserverUnsubscribe!==null}isListening(){return this.isCapturing()}},he=new Kr;function At(e={}){let{maxEvents:t=500,enabled:o=true}=e,{events:r,clearEvents:a,isActive:i}=Mr(he,{maxEvents:t,enabled:o});return{events:r,clearEvents:a,isListening:i}}import{Navigation as Qr,night as _e,monoFont as Jr}from"@buoy-gg/shared-ui/web";import{InlineCopyButton as ze,night as st,monoFont as lt}from"@buoy-gg/shared-ui/web";import{DataViewer as qr}from"@buoy-gg/shared-ui/web/dataViewer";import{jsx as N,jsxs as q}from"react/jsx-runtime";function Xr(e){if(e<1e3)return`${e}ms`;if(e<6e4)return`${(e/1e3).toFixed(1)}s`;let t=Math.floor(e/6e4),o=(e%6e4/1e3).toFixed(0);return`${t}m ${o}s`}function ct({event:e,visitNumber:t,routeTemplate:o}){let r=e.params&&Object.keys(e.params).length>0;return q(c,{style:T.container,children:[q(c,{style:T.section,children:[o&&q(c,{style:T.detailRow,testID:"buoy-routes-detail-template",children:[N(h,{style:T.detailLabel,children:"Template:"}),N(h,{style:T.detailValue,testID:"buoy-routes-detail-template-value",children:o}),N(ze,{value:o,buttonStyle:T.copyButton})]}),e.previousPathname&&q(c,{style:T.detailRow,testID:"buoy-routes-detail-from",children:[N(h,{style:T.detailLabel,children:"From:"}),N(h,{style:T.detailValue,testID:"buoy-routes-detail-from-value",children:e.previousPathname}),N(ze,{value:e.previousPathname,buttonStyle:T.copyButton})]}),q(c,{style:T.detailRow,testID:"buoy-routes-detail-to",children:[N(h,{style:T.detailLabel,children:"To:"}),N(h,{style:T.detailValue,testID:"buoy-routes-detail-to-value",children:e.pathname}),N(ze,{value:e.pathname,buttonStyle:T.copyButton})]})]}),q(c,{style:T.section,children:[e.timeSincePrevious!==void 0&&q(c,{style:T.detailRow,testID:"buoy-routes-detail-duration",children:[N(h,{style:T.detailLabel,children:"Duration:"}),N(h,{style:T.detailValue,testID:"buoy-routes-detail-duration-value",children:Xr(e.timeSincePrevious)})]}),q(c,{style:T.detailRow,testID:"buoy-routes-detail-time",children:[N(h,{style:T.detailLabel,children:"Time:"}),N(h,{style:T.detailValue,testID:"buoy-routes-detail-time-value",children:new Date(e.timestamp).toLocaleString()})]})]}),q(c,{style:T.section,children:[e.segments&&e.segments.length>0&&q(c,{style:T.detailRow,testID:"buoy-routes-detail-segments",children:[N(h,{style:T.detailLabel,children:"Segments:"}),N(h,{style:T.detailValue,testID:"buoy-routes-detail-segments-value",children:e.segments.join(" \u2192 ")}),N(ze,{value:JSON.stringify(e.segments),buttonStyle:T.copyButton})]}),r&&q(c,{style:T.dataViewerContainer,children:[q(c,{style:T.dataViewerHeader,children:[q(h,{style:T.dataViewerTitle,testID:"buoy-routes-detail-params-title",children:["Parameters (",Object.keys(e.params).length,")"]}),N(ze,{value:JSON.stringify(e.params,null,2),buttonStyle:T.copyButton})]}),N(qr,{data:e.params,title:"",showTypeFilter:true,rawMode:true,initialExpanded:true})]}),t>1&&q(c,{style:T.detailRow,testID:"buoy-routes-detail-visited",children:[N(h,{style:T.detailLabel,children:"Visited:"}),q(h,{style:T.detailValue,testID:"buoy-routes-detail-visited-value",children:[t," time",t!==1?"s":""]})]})]})]})}var T=ve.create({container:{gap:12},section:{gap:8},detailRow:{flexDirection:"row",alignItems:"center",gap:8},detailLabel:{fontSize:10,color:st.color.textSecondary,fontFamily:lt,fontWeight:"600",minWidth:70},detailValue:{fontSize:11,color:st.color.text,fontFamily:lt,flex:1},copyButton:{padding:4,borderRadius:4},dataViewerContainer:{marginTop:4},dataViewerHeader:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",marginBottom:8},dataViewerTitle:{fontSize:11,color:st.color.textSecondary,fontFamily:lt,fontWeight:"600"}});function ut(e,t){if(!t||t.length===0)return null;let o="/"+t.map(r=>/^\d+$/.test(r)||/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(r)?"[id]":r).join("/");return o!==e?o:null}function Wt(e,t){if(!t)return e;let o=new Set(e.split("/").filter(Boolean).map(a=>{try{return decodeURIComponent(a)}catch{return a}})),r=[];for(let[a,i]of Object.entries(t)){let n=Array.isArray(i)?i:[i];if(!(n.length>0&&n.every(u=>o.has(String(u)))))for(let u of n)r.push(`${encodeURIComponent(a)}=${encodeURIComponent(String(u))}`)}return r.length?`${e}?${r.join("&")}`:e}function Yr(e){let t=e.indexOf("?");if(t<0)return{pathname:e,params:{}};let o={};for(let r of e.slice(t+1).split("&")){if(!r)continue;let[a,i=""]=r.split("=");try{o[decodeURIComponent(a)]=decodeURIComponent(i)}catch{o[a]=i}}return{pathname:e.slice(0,t),params:o}}import{jsx as Ne,jsxs as jt}from"react/jsx-runtime";function Vt({event:e,visitNumber:t=1,onNavigate:o}){let r=ut(e.pathname,e.segments);return jt(c,{style:ke.container,children:[Ne(Ue,{testID:"buoy-routes-detail-scroll",style:ke.scroll,contentContainerStyle:ke.scrollContent,showsVerticalScrollIndicator:true,children:Ne(ct,{event:e,visitNumber:t,routeTemplate:r})}),o&&Ne(c,{style:ke.footer,children:jt(V,{style:ke.goButton,onPress:()=>o(Wt(e.pathname,e.params)),activeOpacity:.8,testID:"buoy-routes-detail-go",accessibilityRole:"button",accessibilityLabel:`Go to route ${e.pathname}`,children:[Ne(Qr,{size:16,color:_e.color.onAccent}),Ne(h,{style:ke.goButtonText,children:"Go to route"})]})})]})}var ke=ve.create({container:{flex:1,backgroundColor:"transparent"},scroll:{flex:1},scrollContent:{padding:14},footer:{paddingHorizontal:16,paddingVertical:12,backgroundColor:"transparent",borderTopWidth:1,borderTopColor:_e.color.border},goButton:{flexDirection:"row",alignItems:"center",justifyContent:"center",gap:8,backgroundColor:_e.color.accent,paddingVertical:12,borderRadius:8},goButtonText:{fontSize:13,fontWeight:"600",color:_e.color.onAccent,fontFamily:Jr,textTransform:"uppercase",letterSpacing:.5}});import{Filter as Ot,DynamicFilterView as Zr}from"@buoy-gg/shared-ui/web";import{jsx as ea}from"react/jsx-runtime";function ta({ignoredPatterns:e,onTogglePattern:t,onAddPattern:o,availablePathnames:r=[]}){return ea(Zr,{...{addFilterSection:{enabled:true,placeholder:"Enter pattern (e.g., /_sitemap)",title:"ACTIVE FILTERS",icon:Ot},availableItemsSection:{enabled:true,title:"AVAILABLE ROUTES FROM EVENTS",emptyMessage:"No routes available. Routes from navigation events will appear here.",items:r},howItWorksSection:{enabled:true,title:"HOW FILTERS WORK",description:"Filtered routes will not appear in the route events list. Patterns match if the route contains the specified text.",examples:["\u2022 /_sitemap \u2192 filters /_sitemap routes","\u2022 /api \u2192 filters /api/users, /api/posts","\u2022 [id] \u2192 filters all routes with [id] param"],icon:Ot},onPatternToggle:t,onPatternAdd:o,activePatterns:e}})}import{useState as Be,useCallback as Ae,useMemo as Ke,useEffect as oa}from"react";import{night as b,ToolEmptyState as ra,monoFont as _}from"@buoy-gg/shared-ui/web";import{isCapacitorNative as aa}from"@buoy-gg/license/web";import{useSafeRouter as na}from"@buoy-gg/shared-ui/web";import{Search as Ht,ChevronDown as Mt,ChevronRight as Ut,Home as ia,InlineCopyButton as sa,CopyButton as la,RefreshCw as ca,formatRelativeTime as ua,ProUpgradeModal as da}from"@buoy-gg/shared-ui/web";import{useIsPro as pa}from"@buoy-gg/license/web";import{useState as ma,useEffect as Gt,useMemo as Se,useCallback as ha}from"react";var ge=class{static parseRouteTree(e){if(!e)return[];let t=[];return this.traverseNode(e,"",t,0),t}static traverseNode(e,t,o,r){let a=this.buildPath(e,t),i=this.detectRouteType(e),n=this.shouldIncludeRoute(e),u={path:a,name:e.route,type:i,params:this.extractParams(e),nodeType:e.type,contextKey:e.contextKey,isInternal:e.internal??false,children:[],depth:r};n&&o.push(u);for(let l of e.children)this.traverseNode(l,a,n?u.children:o,r+1)}static buildPath(e,t){if(e.type==="layout"&&e.route==="_layout"||e.route.startsWith("(")&&e.route.endsWith(")"))return t;if(e.route==="index")return t||"/";let o=e.route;return!t||t==="/"?`/${o}`:`${t}/${o}`}static detectRouteType(e){let t=e.route;return e.dynamic?.some(o=>o.notFound)?"not-found":e.dynamic?.some(o=>o.deep)?"catch-all":e.dynamic&&e.dynamic.length>0?"dynamic":e.type==="layout"?"layout":t.startsWith("(")&&t.endsWith(")")?"group":t==="index"?"index":"static"}static extractParams(e){return!e.dynamic||e.dynamic.length===0?[]:e.dynamic.map(t=>t.name)}static shouldIncludeRoute(e){return!(e.internal||e.generated||e.type==="api")}static organizeRoutes(e){let t=[],o=this.flattenRoutes(e).filter(n=>n.type==="static"||n.type==="index"),r=this.flattenRoutes(e).filter(n=>n.type==="dynamic"||n.type==="catch-all"),a=this.flattenRoutes(e).filter(n=>n.type==="layout"),i=this.flattenRoutes(e).filter(n=>n.type==="group");return o.length>0&&t.push({title:"Static Routes",icon:"",routes:o}),r.length>0&&t.push({title:"Dynamic Routes",icon:"",description:"Routes that accept parameters",routes:r}),a.length>0&&t.push({title:"Layouts",icon:"",description:"Shared UI for nested screens",routes:a}),i.length>0&&t.push({title:"Route Groups",icon:"",routes:i}),t}static flattenRoutes(e){let t=[];function o(r){t.push(r),r.children.forEach(o)}return e.forEach(o),t}static getRouteStats(e){let t=this.flattenRoutes(e);return{total:t.length,static:t.filter(o=>o.type==="static").length,dynamic:t.filter(o=>o.type==="dynamic").length,catchAll:t.filter(o=>o.type==="catch-all").length,layouts:t.filter(o=>o.type==="layout").length,groups:t.filter(o=>o.type==="group").length}}static filterRoutes(e,t){if(!t)return e;let o=t.toLowerCase();return this.flattenRoutes(e).filter(r=>r.path.toLowerCase().includes(o)||r.name.toLowerCase().includes(o)||r.type.toLowerCase().includes(o)||r.params.some(a=>a.toLowerCase().includes(o)))}static buildTreeString(e,t=0){let o="";return e.forEach((r,a)=>{let i=a===e.length-1,n=`${this.buildTreePrefix(t,i)}${r.path}`;r.params.length>0&&(n+=` { ${r.params.join(", ")} }`),o+=n+`
|
|
2
|
-
`,r.children.length>0&&(o+=this.buildTreeString(r.children,t+1))}),o}static buildTreePrefix(e,t){return e===0?"":" ".repeat(e-1)+(t?"\u2514\u2500 ":"\u251C\u2500 ")}static sortRoutes(e,t="path"){let o=[...e];return o.sort((r,a)=>{switch(t){case"path":return r.path.localeCompare(a.path);case"type":return r.type.localeCompare(a.type);case"name":return r.name.localeCompare(a.name);default:return 0}}),o}static findRouteByPath(e,t){return this.flattenRoutes(e).find(o=>o.path===t)||null}static getParentRoutes(e,t){let o=[],r=this.flattenRoutes(e);if(!r.find(
|
|
1
|
+
"use client";var $t=Object.defineProperty;var Bo=Object.getOwnPropertyDescriptor;var Eo=Object.getOwnPropertyNames;var Do=Object.prototype.hasOwnProperty;var Po=(e,t)=>{for(var o in t)$t(e,o,{get:t[o],enumerable:true})},zt=(e,t,o,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of Eo(t))!Do.call(e,a)&&a!==o&&$t(e,a,{get:()=>t[a],enumerable:!(r=Bo(t,a))||r.enumerable});return e},Lo=(e,t,o)=>(zt(e,t,"default"),o&&zt(o,t,"default"));var Mn=(()=>{try{let e=globalThis.Capacitor;if(e&&typeof e.isNativePlatform=="function"&&e.isNativePlatform())return e.DEBUG===true}catch{}return process.env.NODE_ENV!=="production"})();typeof window<"u"&&typeof globalThis.global>"u"&&(globalThis.global=globalThis);import{RoutesIcon as $o}from"@buoy-gg/floating-tools-core/web";import{useState as Ie,useCallback as pe,useEffect as Ft,useRef as zo,useMemo as Re}from"react";var At={};Po(At,{AccessibilityInfo:()=>Wo,ActivityIndicator:()=>Ar,Alert:()=>M,Animated:()=>jo,AppRegistry:()=>Oo,AppState:()=>Ho,Appearance:()=>Vo,BackHandler:()=>Mo,Button:()=>Nr,CheckBox:()=>ar,Clipboard:()=>Uo,DeviceEventEmitter:()=>vr,Dimensions:()=>Ko,Easing:()=>Go,FlatList:()=>Nt,I18nManager:()=>_o,Image:()=>nr,ImageBackground:()=>ir,InteractionManager:()=>Zo,Keyboard:()=>Jo,KeyboardAvoidingView:()=>sr,LayoutAnimation:()=>Qo,Linking:()=>qo,LogBox:()=>br,Modal:()=>zr,NativeEventEmitter:()=>Yo,NativeModules:()=>No,PanResponder:()=>Xo,Picker:()=>lr,PixelRatio:()=>er,Platform:()=>st,Pressable:()=>$r,ProgressBar:()=>cr,RefreshControl:()=>ur,SafeAreaView:()=>dr,ScrollView:()=>_e,SectionList:()=>pr,Share:()=>tr,StatusBar:()=>mr,StyleSheet:()=>ve,Switch:()=>Fr,Text:()=>m,TextInput:()=>Ot,Touchable:()=>hr,TouchableHighlight:()=>Pr,TouchableNativeFeedback:()=>gr,TouchableOpacity:()=>j,TouchableWithoutFeedback:()=>Lr,UIManager:()=>or,Vibration:()=>rr,View:()=>u,VirtualizedList:()=>fr,YellowBox:()=>yr,findNodeHandle:()=>Wr,unstable_createElement:()=>Ao,useColorScheme:()=>xr,useLocaleContext:()=>Sr,useWindowDimensions:()=>wr});Lo(At,Fo);import*as Fo from"react-native-web";import{unstable_createElement as Ao,NativeModules as No,AccessibilityInfo as Wo,Animated as jo,Appearance as Vo,AppRegistry as Oo,AppState as Ho,BackHandler as Mo,Clipboard as Uo,Dimensions as Ko,Easing as Go,I18nManager as _o,Keyboard as Jo,InteractionManager as Zo,LayoutAnimation as Qo,Linking as qo,NativeEventEmitter as Yo,PanResponder as Xo,PixelRatio as er,Platform as st,Share as tr,StyleSheet as ve,UIManager as or,Vibration as rr,CheckBox as ar,FlatList as Nt,Image as nr,ImageBackground as ir,KeyboardAvoidingView as sr,Picker as lr,ProgressBar as cr,RefreshControl as ur,SafeAreaView as dr,SectionList as pr,StatusBar as mr,Touchable as hr,TouchableNativeFeedback as gr,VirtualizedList as fr,YellowBox as yr,LogBox as br,DeviceEventEmitter as vr,useColorScheme as xr,useLocaleContext as Sr,useWindowDimensions as wr}from"react-native-web";import*as te from"react-native-web";import{createElement as lt,forwardRef as Wt,useCallback as Tr,useRef as Cr}from"react";import{useEffect as kr,useState as Ir}from"react";import{createPortal as Rr}from"react-dom";var Br='-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif';import{jsx as Er}from"react/jsx-runtime";var ze=Symbol.for("@buoy-gg/portal-host"),jt=e=>{if(!(e instanceof Element))return false;if(e.closest("input, textarea, select"))return true;let t=e.closest("[contenteditable]")?.getAttribute("contenteditable")?.toLowerCase();return t===""||t==="true"||t==="plaintext-only"};function Vt(){let e=document;if(e[ze])return e[ze].host;let t=document.createElement("div");t.dataset.buoyPortalHost="",Object.assign(t.style,{position:"fixed",inset:"0",zIndex:"2147483647",pointerEvents:"none",fontFamily:Br});let o=()=>{let s=document.fullscreenElement,p=s&&s.tagName!=="CANVAS"?s:document.body;t.parentElement!==p&&p.appendChild(t)},r=new Map,a=s=>{(!t.contains(s.target)||!jt(s.target))&&r.set(s.code||s.key,{key:s.key,code:s.code,location:s.location,keyCode:s.keyCode,which:s.which,altKey:s.altKey,ctrlKey:s.ctrlKey,metaKey:s.metaKey,shiftKey:s.shiftKey})},n=s=>{r.delete(s.code||s.key)},i=()=>r.clear(),d=()=>{let s=[...r.values()];r.clear();for(let p of s)document.dispatchEvent(new KeyboardEvent("keyup",{...p,bubbles:true}))},l=s=>{jt(s.target)&&s.stopPropagation()},g=s=>s.stopPropagation();return o(),document.addEventListener("fullscreenchange",o),document.addEventListener("keydown",a,true),document.addEventListener("keyup",n,true),window.addEventListener("blur",i),t.addEventListener("focusin",d),t.addEventListener("keydown",l),t.addEventListener("keyup",l),t.addEventListener("keypress",l),t.addEventListener("wheel",g,{passive:true}),e[ze]={host:t,users:0,dispose:()=>{document.removeEventListener("fullscreenchange",o),document.removeEventListener("keydown",a,true),document.removeEventListener("keyup",n,true),window.removeEventListener("blur",i),t.remove(),delete e[ze]}},t}function Dr({children:e}){let[t,o]=Ir(null);return kr(()=>{let r=Vt(),a=document[ze];return a.users++,o(r),()=>{--a.users===0&&a.dispose()}},[]),t?Rr(Er("div",{"data-buoy-root":"",style:{display:"contents",pointerEvents:"auto"},children:e}),t):null}function ae(e){let t=Wt((r,a)=>{let{accessibilityState:n,accessibilityValue:i,...d}=r;for(let l of["busy","checked","disabled","expanded","selected"])n?.[l]!==void 0&&d[`aria-${l}`]===void 0&&(d[`aria-${l}`]=n[l]);for(let[l,g]of Object.entries({min:"valuemin",max:"valuemax",now:"valuenow",text:"valuetext"}))i?.[l]!==void 0&&d[`aria-${g}`]===void 0&&(d[`aria-${g}`]=i[l]);return lt(e,{...d,ref:a})}),o=e.State;return o&&Object.assign(t,{State:o}),t.displayName=e.displayName??e.name??"NativeWebView",t}var u=ae(te.View),m=ae(te.Text),Ot=ae(te.TextInput),j=ae(te.TouchableOpacity),Pr=ae(te.TouchableHighlight),Lr=ae(te.TouchableWithoutFeedback),$r=ae(te.Pressable),_e=ae(te.ScrollView),Ht=Wt((e,t)=>{let o=Cr(null),r=Tr(a=>{if(a){let n=a;for(;n.parentElement&&n.parentElement!==document.body;)n=n.parentElement;n.parentElement===document.body&&(o.current=n,Object.assign(n.style,{position:"relative",zIndex:"2147483647",pointerEvents:"auto"}),Vt().appendChild(n))}else o.current&&(document.body.appendChild(o.current),o.current=null);typeof t=="function"?t(a):t&&(t.current=a)},[t]);return lt(Dr,null,lt(te.Modal,{...e,ref:r}))});Ht.displayName="Modal";var zr=ae(Ht),Fr=ae(te.Switch),Ar=ae(te.ActivityIndicator),Nr=ae(te.Button),Wr=te.findNodeHandle,M={alert(e,t,o,r){if(typeof document>"u")return;let a=document.createElement("dialog");a.dataset.buoyRoot="",a.setAttribute("aria-label",e),a.style.cssText="position:fixed;inset:0;margin:auto;width:min(440px,90vw);padding:24px;border:1px solid #475569;border-radius:14px;background:#17212e;color:#f1f5f9;font:14px system-ui;box-shadow:0 20px 80px #0008;z-index:2147483647";let n=document.createElement("h2");if(n.textContent=e,n.style.cssText="font-size:18px;margin:0 0 12px",a.appendChild(n),t){let g=document.createElement("p");g.textContent=t,g.style.cssText="line-height:1.5;white-space:pre-wrap;margin:0 0 20px",a.appendChild(g)}let i=document.createElement("div");i.style.cssText="display:flex;justify-content:flex-end;flex-wrap:wrap;gap:8px";let d=o?.length?o:[{text:"OK"}],l=()=>{a.close?.(),a.remove()};for(let g of d){let s=document.createElement("button");s.type="button",s.textContent=g.text??"OK",s.style.cssText=`padding:9px 14px;border:1px solid #64748b;border-radius:7px;color:white;background:${g.style==="destructive"?"#a52b38":"#283a4d"};cursor:pointer;font:inherit`,s.onclick=()=>{l(),g.onPress?.()},i.appendChild(s)}a.addEventListener("cancel",g=>{g.preventDefault(),r?.cancelable!==false&&(l(),r?.onDismiss?.())}),a.appendChild(i),document.body.appendChild(a),a.showModal?a.showModal():a.setAttribute("open","")}};import{browserRouter as Yn}from"@buoy-gg/shared-ui/web/utils";function jr(){return null}import{useSafeRouter as Vr,isExpoRouterAvailable as Or,windowDragProps as Hr,ToolEmptyState as Mr,resolveListEmptyState as Ur,usePersistedState as ct,monoFont as Je}from"@buoy-gg/shared-ui/web";import{JsModal as Kr,ModalHeader as se,TabSelector as Gr,formatRelativeTime as _r,devToolsStorageKeys as Fe,Trash2 as Jr,Filter as Zr,SearchBar as Mt,ToolbarCopyButton as ut,Lock as Qr,ProUpgradeModal as qr,PowerToggleButton as Yr,buoyColors as Xr,night as J,TickProvider as Ut,useLimit as ea}from"@buoy-gg/shared-ui/web";import{useIsPro as ta}from"@buoy-gg/license/web";import{useEventStoreEvents as oa}from"@buoy-gg/shared-ui/web";import{BaseEventStore as ra,devToolsStorageKeys as aa,persistentStorage as na}from"@buoy-gg/shared-ui/web";var Kt=class{constructor(){this.listeners=new Set}emit(e){this.listeners.forEach(t=>{try{t(e)}catch(o){console.error("[Buoy]","[RouteObserver] Error in listener:",o)}})}addListener(e){return this.listeners.add(e),()=>this.listeners.delete(e)}removeListener(e){this.listeners.delete(e)}},Ae=new Kt;var ia=class extends ra{constructor(){super({storeName:"route-events",maxEvents:500});this.routeObserverUnsubscribe=null;this.bootCaptureRelease=null;this.bootCaptureHydrated=false}setBootCapture(e){e&&!this.bootCaptureRelease?this.bootCaptureRelease=this.subscribeToEvents(()=>{}):!e&&this.bootCaptureRelease&&(this.bootCaptureRelease(),this.bootCaptureRelease=null)}hydrateBootCapture(){this.bootCaptureHydrated||(this.bootCaptureHydrated=true,na.getItem(aa.routeEvents.isMonitoring()).then(e=>{this.bootCaptureRelease||this.setBootCapture(e!=="false")}).catch(()=>this.setBootCapture(true)))}startCapturing(){this.routeObserverUnsubscribe||(this.routeObserverUnsubscribe=Ae.addListener(e=>{this.addEvent(e)}))}stopCapturing(){this.routeObserverUnsubscribe&&(this.routeObserverUnsubscribe(),this.routeObserverUnsubscribe=null)}isCapturing(){return this.routeObserverUnsubscribe!==null}isListening(){return this.isCapturing()}},fe=new ia;function Gt(e={}){let{maxEvents:t=500,enabled:o=true}=e,{events:r,clearEvents:a,isActive:n}=oa(fe,{maxEvents:t,enabled:o});return{events:r,clearEvents:a,isListening:n}}import{Navigation as sa,night as Ze,monoFont as la}from"@buoy-gg/shared-ui/web";import{InlineCopyButton as Ne,night as dt,monoFont as pt}from"@buoy-gg/shared-ui/web";import{DataViewer as ca}from"@buoy-gg/shared-ui/web/dataViewer";import{jsx as F,jsxs as U}from"react/jsx-runtime";function ua(e){if(e<1e3)return`${e}ms`;if(e<6e4)return`${(e/1e3).toFixed(1)}s`;let t=Math.floor(e/6e4),o=(e%6e4/1e3).toFixed(0);return`${t}m ${o}s`}function mt({event:e,visitNumber:t,routeTemplate:o}){let r=e.params&&Object.keys(e.params).length>0;return U(u,{style:S.container,children:[U(u,{style:S.section,children:[e.routeName&&U(u,{style:S.detailRow,children:[F(m,{style:S.detailLabel,children:"Name:"}),F(m,{style:S.detailValue,testID:"buoy-routes-detail-name",children:e.routeName})]}),e.matchedPath&&U(u,{style:S.detailRow,children:[F(m,{style:S.detailLabel,children:"Match:"}),F(m,{style:S.detailValue,testID:"buoy-routes-detail-match",children:e.matchedPath})]}),o&&U(u,{style:S.detailRow,testID:"buoy-routes-detail-template",children:[F(m,{style:S.detailLabel,children:"Template:"}),F(m,{style:S.detailValue,testID:"buoy-routes-detail-template-value",children:o}),F(Ne,{value:o,buttonStyle:S.copyButton})]}),e.previousPathname&&U(u,{style:S.detailRow,testID:"buoy-routes-detail-from",children:[F(m,{style:S.detailLabel,children:"From:"}),F(m,{style:S.detailValue,testID:"buoy-routes-detail-from-value",children:e.previousPathname}),F(Ne,{value:e.previousPathname,buttonStyle:S.copyButton})]}),U(u,{style:S.detailRow,testID:"buoy-routes-detail-to",children:[F(m,{style:S.detailLabel,children:"To:"}),F(m,{style:S.detailValue,testID:"buoy-routes-detail-to-value",children:e.pathname}),F(Ne,{value:e.pathname,buttonStyle:S.copyButton})]})]}),U(u,{style:S.section,children:[e.timeSincePrevious!==void 0&&U(u,{style:S.detailRow,testID:"buoy-routes-detail-duration",children:[F(m,{style:S.detailLabel,children:"Duration:"}),F(m,{style:S.detailValue,testID:"buoy-routes-detail-duration-value",children:ua(e.timeSincePrevious)})]}),U(u,{style:S.detailRow,testID:"buoy-routes-detail-time",children:[F(m,{style:S.detailLabel,children:"Time:"}),F(m,{style:S.detailValue,testID:"buoy-routes-detail-time-value",children:new Date(e.timestamp).toLocaleString()})]})]}),U(u,{style:S.section,children:[e.segments&&e.segments.length>0&&U(u,{style:S.detailRow,testID:"buoy-routes-detail-segments",children:[F(m,{style:S.detailLabel,children:"Segments:"}),F(m,{style:S.detailValue,testID:"buoy-routes-detail-segments-value",children:e.segments.join(" \u2192 ")}),F(Ne,{value:JSON.stringify(e.segments),buttonStyle:S.copyButton})]}),r&&U(u,{style:S.dataViewerContainer,children:[U(u,{style:S.dataViewerHeader,children:[U(m,{style:S.dataViewerTitle,testID:"buoy-routes-detail-params-title",children:["Parameters (",Object.keys(e.params).length,")"]}),F(Ne,{value:JSON.stringify(e.params,null,2),buttonStyle:S.copyButton})]}),F(ca,{data:e.params,title:"",showTypeFilter:true,rawMode:true,initialExpanded:true})]}),t>1&&U(u,{style:S.detailRow,testID:"buoy-routes-detail-visited",children:[F(m,{style:S.detailLabel,children:"Visited:"}),U(m,{style:S.detailValue,testID:"buoy-routes-detail-visited-value",children:[t," time",t!==1?"s":""]})]})]})]})}var S=ve.create({container:{gap:12},section:{gap:8},detailRow:{flexDirection:"row",alignItems:"center",gap:8},detailLabel:{fontSize:10,color:dt.color.textSecondary,fontFamily:pt,fontWeight:"600",minWidth:70},detailValue:{fontSize:11,color:dt.color.text,fontFamily:pt,flex:1},copyButton:{padding:4,borderRadius:4},dataViewerContainer:{marginTop:4},dataViewerHeader:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",marginBottom:8},dataViewerTitle:{fontSize:11,color:dt.color.textSecondary,fontFamily:pt,fontWeight:"600"}});function ht(e,t){if(!t||t.length===0)return null;let o="/"+t.map(r=>/^\d+$/.test(r)||/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(r)?"[id]":r).join("/");return o!==e?o:null}function _t(e,t){if(!t)return e;let o=new Set(e.split("/").filter(Boolean).map(a=>{try{return decodeURIComponent(a)}catch{return a}})),r=[];for(let[a,n]of Object.entries(t)){let i=Array.isArray(n)?n:[n];if(!(i.length>0&&i.every(d=>o.has(String(d)))))for(let d of i)r.push(`${encodeURIComponent(a)}=${encodeURIComponent(String(d))}`)}return r.length?`${e}?${r.join("&")}`:e}function da(e){let t=e.indexOf("?");if(t<0)return{pathname:e,params:{}};let o={};for(let r of e.slice(t+1).split("&")){if(!r)continue;let[a,n=""]=r.split("=");try{o[decodeURIComponent(a)]=decodeURIComponent(n)}catch{o[a]=n}}return{pathname:e.slice(0,t),params:o}}import{jsx as We,jsxs as Jt}from"react/jsx-runtime";function Zt({event:e,visitNumber:t=1,onNavigate:o}){let r=ht(e.pathname,e.segments);return Jt(u,{style:Be.container,children:[We(_e,{testID:"buoy-routes-detail-scroll",style:Be.scroll,contentContainerStyle:Be.scrollContent,showsVerticalScrollIndicator:true,children:We(mt,{event:e,visitNumber:t,routeTemplate:r})}),o&&We(u,{style:Be.footer,children:Jt(j,{style:Be.goButton,onPress:()=>o(_t(e.pathname,e.params)),activeOpacity:.8,testID:"buoy-routes-detail-go",accessibilityRole:"button",accessibilityLabel:`Go to route ${e.pathname}`,children:[We(sa,{size:16,color:Ze.color.onAccent}),We(m,{style:Be.goButtonText,children:"Go to route"})]})})]})}var Be=ve.create({container:{flex:1,backgroundColor:"transparent"},scroll:{flex:1},scrollContent:{padding:14},footer:{paddingHorizontal:16,paddingVertical:12,backgroundColor:"transparent",borderTopWidth:1,borderTopColor:Ze.color.border},goButton:{flexDirection:"row",alignItems:"center",justifyContent:"center",gap:8,backgroundColor:Ze.color.accent,paddingVertical:12,borderRadius:8},goButtonText:{fontSize:13,fontWeight:"600",color:Ze.color.onAccent,fontFamily:la,textTransform:"uppercase",letterSpacing:.5}});import{Filter as Qt,DynamicFilterView as pa}from"@buoy-gg/shared-ui/web";import{jsx as ma}from"react/jsx-runtime";function ha({ignoredPatterns:e,onTogglePattern:t,onAddPattern:o,availablePathnames:r=[]}){return ma(pa,{...{addFilterSection:{enabled:true,placeholder:"Enter pattern (e.g., /_sitemap)",title:"ACTIVE FILTERS",icon:Qt},availableItemsSection:{enabled:true,title:"AVAILABLE ROUTES FROM EVENTS",emptyMessage:"No routes available. Routes from navigation events will appear here.",items:r},howItWorksSection:{enabled:true,title:"HOW FILTERS WORK",description:"Filtered routes will not appear in the route events list. Patterns match if the route contains the specified text.",examples:["\u2022 /_sitemap \u2192 filters /_sitemap routes","\u2022 /api \u2192 filters /api/users, /api/posts","\u2022 [id] \u2192 filters all routes with [id] param"],icon:Qt},onPatternToggle:t,onPatternAdd:o,activePatterns:e}})}import{useState as Ee,useCallback as je,useMemo as Qe,useEffect as ga}from"react";import{night as b,ToolEmptyState as fa,monoFont as Z}from"@buoy-gg/shared-ui/web";import{isCapacitorNative as ya}from"@buoy-gg/license/web";import{useSafeRouter as ba}from"@buoy-gg/shared-ui/web";import{Search as qt,ChevronDown as Yt,ChevronRight as Xt,Home as va,InlineCopyButton as xa,CopyButton as Sa,RefreshCw as wa,formatRelativeTime as Ta,ProUpgradeModal as Ca}from"@buoy-gg/shared-ui/web";import{useIsPro as ka}from"@buoy-gg/license/web";import{useState as Ia,useEffect as eo,useMemo as Se,useCallback as Ra}from"react";var ye=class{static parseRouteTree(e){if(!e)return[];let t=[];return this.traverseNode(e,"",t,0),t}static traverseNode(e,t,o,r){let a=this.buildPath(e,t),n=this.detectRouteType(e),i=this.shouldIncludeRoute(e),d={path:a,name:e.route,type:n,params:this.extractParams(e),nodeType:e.type,contextKey:e.contextKey,isInternal:e.internal??false,children:[],depth:r};i&&o.push(d);for(let l of e.children)this.traverseNode(l,a,i?d.children:o,r+1)}static buildPath(e,t){if(e.type==="layout"&&e.route==="_layout"||e.route.startsWith("(")&&e.route.endsWith(")"))return t;if(e.route==="index")return t||"/";let o=e.route;return!t||t==="/"?`/${o}`:`${t}/${o}`}static detectRouteType(e){let t=e.route;return e.dynamic?.some(o=>o.notFound)?"not-found":e.dynamic?.some(o=>o.deep)?"catch-all":e.dynamic&&e.dynamic.length>0?"dynamic":e.type==="layout"?"layout":t.startsWith("(")&&t.endsWith(")")?"group":t==="index"?"index":"static"}static extractParams(e){return!e.dynamic||e.dynamic.length===0?[]:e.dynamic.map(t=>t.name)}static shouldIncludeRoute(e){return!(e.internal||e.generated||e.type==="api")}static organizeRoutes(e){let t=[],o=this.flattenRoutes(e).filter(i=>i.type==="static"||i.type==="index"),r=this.flattenRoutes(e).filter(i=>i.type==="dynamic"||i.type==="catch-all"),a=this.flattenRoutes(e).filter(i=>i.type==="layout"),n=this.flattenRoutes(e).filter(i=>i.type==="group");return o.length>0&&t.push({title:"Static Routes",icon:"",routes:o}),r.length>0&&t.push({title:"Dynamic Routes",icon:"",description:"Routes that accept parameters",routes:r}),a.length>0&&t.push({title:"Layouts",icon:"",description:"Shared UI for nested screens",routes:a}),n.length>0&&t.push({title:"Route Groups",icon:"",routes:n}),t}static flattenRoutes(e){let t=[];function o(r){t.push(r),r.children.forEach(o)}return e.forEach(o),t}static getRouteStats(e){let t=this.flattenRoutes(e);return{total:t.length,static:t.filter(o=>o.type==="static").length,dynamic:t.filter(o=>o.type==="dynamic").length,catchAll:t.filter(o=>o.type==="catch-all").length,layouts:t.filter(o=>o.type==="layout").length,groups:t.filter(o=>o.type==="group").length}}static filterRoutes(e,t){if(!t)return e;let o=t.toLowerCase();return this.flattenRoutes(e).filter(r=>r.path.toLowerCase().includes(o)||r.name.toLowerCase().includes(o)||r.type.toLowerCase().includes(o)||r.params.some(a=>a.toLowerCase().includes(o)))}static buildTreeString(e,t=0){let o="";return e.forEach((r,a)=>{let n=a===e.length-1,i=`${this.buildTreePrefix(t,n)}${r.path}`;r.params.length>0&&(i+=` { ${r.params.join(", ")} }`),o+=i+`
|
|
2
|
+
`,r.children.length>0&&(o+=this.buildTreeString(r.children,t+1))}),o}static buildTreePrefix(e,t){return e===0?"":" ".repeat(e-1)+(t?"\u2514\u2500 ":"\u251C\u2500 ")}static sortRoutes(e,t="path"){let o=[...e];return o.sort((r,a)=>{switch(t){case"path":return r.path.localeCompare(a.path);case"type":return r.type.localeCompare(a.type);case"name":return r.name.localeCompare(a.name);default:return 0}}),o}static findRouteByPath(e,t){return this.flattenRoutes(e).find(o=>o.path===t)||null}static getParentRoutes(e,t){let o=[],r=this.flattenRoutes(e);if(!r.find(i=>i.path===t))return o;let a=t.split("/").filter(Boolean),n="";for(let i=0;i<a.length-1;i++){n+="/"+a[i];let d=r.find(l=>l.path===n);d&&o.push(d)}return o}};import{getBrowserHref as Ba}from"@buoy-gg/shared-ui/web/utils";var De=new Map,gt=null;function Ea(e){for(let o of e)De.set(o,(De.get(o)??0)+1);gt=Date.now();let t=true;return()=>{if(t){t=false;for(let o of e){let r=(De.get(o)??1)-1;r?De.set(o,r):De.delete(o)}gt=Date.now()}}}function ft(){return[...De.keys()]}function Da(){return gt}function to(e){let t={segments:e.split("/").filter(Boolean),params:{}},o=ft();if(o.includes(e))return t;for(let r of o){let a=r.split("/").filter(Boolean),n=[],i=a.map(s=>{let p=/^\[(\.\.\.)?([^\]]+)\]$/.exec(s);return p?(n.push({name:p[2],deep:!!p[1]}),p[1]?"(.+)":"([^/]+)"):s.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}),d=new RegExp("^/"+i.join("/")+"/?$").exec(e);if(!d)continue;let l=s=>{try{return decodeURIComponent(s)}catch{return s}},g={};return n.forEach(({name:s,deep:p},w)=>{let L=d[w+1];g[s]=p?L.split("/").map(l):l(L)}),{segments:a,params:g}}return t}var yt=0;function Pa(){yt++;let e=true;return()=>{e&&(e=false,yt--)}}function La(){return yt>0}function bt(){return typeof window<"u"}function Ve(){return bt()?{route:"",type:"layout",contextKey:"browser",children:[...new Set([...ft(),new URL(Ba()).pathname])].map(e=>({route:e.replace(/^\//,"")||"index",type:"route",contextKey:e,children:[],dynamic:e.split("/").flatMap(t=>{let o=/^\[(\.\.\.)?([^\]]+)\]$/.exec(t);return o?[{name:o[2],deep:!!o[1]}]:[]})}))}:null}function vt(){return{source:null,lastLoadedAt:Da()}}function $a(){return ft().length>0}function qe(e={}){let{searchQuery:t="",sortBy:o="path",autoRefresh:r=false,refreshInterval:a=1e3,injectedRoutes:n,injectedSource:i=null,injectedLastUpdatedAt:d=null}=e,l=n!=null,[g,s]=Ia(()=>{let B=Ve(),_=vt();return{node:B,version:0,lastUpdatedAt:_.lastLoadedAt,source:_.source}}),p=g.node,w=g.version,L=g.lastUpdatedAt,G=g.source,$=Ra(()=>{s(B=>{let _=Ve(),q=vt();return{node:_,version:B.version+1,lastUpdatedAt:q.lastLoadedAt,source:q.source}})},[]);eo(()=>{if(p||l||!bt())return;let B=0,_=100,q=()=>{B++,$(),B<_&&(N=setTimeout(q,100))},N=setTimeout(q,100);return()=>clearTimeout(N)},[p,$,l]),eo(()=>{if(!r)return;let B=setInterval($,a);return()=>clearInterval(B)},[r,a,$]);let E=l?n.length>0:!!p,C=l?true:bt(),I=Se(()=>l?n:p?ye.parseRouteTree(p):[],[p,w,l,n]),re=Se(()=>ye.sortRoutes(I,o),[I,o]),D=Se(()=>t?ye.filterRoutes(re,t):re,[re,t]),Q=Se(()=>ye.organizeRoutes(D),[D]),he=Se(()=>ye.getRouteStats(I),[I]);return{routes:re,groups:Q,stats:he,filteredRoutes:D,isLoaded:E,isSupported:C,refresh:$,findRoute:B=>ye.findRouteByPath(I,B),getParents:B=>ye.getParentRoutes(I,B),lastUpdatedAt:l?d:L,source:l?i:G}}function za(e){let{findRoute:t}=qe();return Se(()=>t(e),[t,e])}function Fa(e){let{getParents:t}=qe();return Se(()=>t(e),[t,e])}function xt(e){return String(e).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"root"}function Aa(e,t){return`buoy-routes-event-row-${xt(e)}-${t}`}function Na(e){return`buoy-routes-route-${xt(e)}`}function oo(e){return`buoy-routes-group-${xt(e)}`}function Wa(e){return`buoy-routes-stack-item-${e}`}import{jsx as h,jsxs as A}from"react/jsx-runtime";var ee=st.OS==="web"&&!ya(),Ye=ee?22:16,ja={path:"/",name:"index",type:"index",params:[],nodeType:"route",contextKey:"/",isInternal:false,children:[],depth:0};function St({style:e,injectedRoutes:t,injectedSource:o,injectedLastUpdatedAt:r,onNavigateRoute:a}){let[n,i]=Ee(""),[d,l]=Ee(false),[g,s]=Ee(new Set(["Static Routes","Dynamic Routes"])),[p,w]=Ee(false),[L,G]=Ee(false),$=ka();ga(()=>{L&&$&&G(false)},[L,$]);let E=ba(),{groups:C,stats:I,isLoaded:re,isSupported:D,filteredRoutes:Q,routes:he,refresh:B,lastUpdatedAt:_,source:q}=qe({searchQuery:n,sortBy:"path",injectedRoutes:t,injectedSource:o,injectedLastUpdatedAt:r}),N=Qe(()=>({summary:{total:I.total,static:I.static,dynamic:I.dynamic,layouts:I.layouts,groups:I.groups,timestamp:new Date().toISOString()},groups:C.map(x=>({title:x.title,description:x.description,count:x.routes.length,routes:x.routes.map(R=>({path:R.path,name:R.name,type:R.type,params:R.params,depth:R.depth,hasChildren:R.children.length>0,childrenCount:R.children.length}))})),allRoutes:he.map(x=>x.path)}),[C,I,he]),we=je(x=>{s(R=>{let Y=new Set(R);return Y.has(x)?Y.delete(x):Y.add(x),Y})},[]),ce=je((x,R=0,Y={})=>{let Le=x.params;if(R>=Le.length){let W=x.path;Object.entries(Y).forEach(([be,ie])=>{x.type==="catch-all"?W=W.replace(`[...${be}]`,ie):W=W.replace(`[${be}]`,ie)});try{E.push(W)}catch(be){M.alert("Navigation Error",String(be))}return}let Te=Le[R],Ue=x.type==="catch-all"?`[...${Te}]`:`[${Te}]`,$e="Enter Parameter Value",Ke=`Enter value for ${Ue}:
|
|
3
3
|
|
|
4
|
-
Route: ${x.path}`,[{text:"Cancel",style:"cancel"},{text:B<Pe.length-1?"Next":"Navigate",onPress:ne=>{if(ne&&ne.trim()){let ye={...Z,[Le]:ne.trim()};fe(x,B+1,ye)}else J.alert("Invalid Value","Please enter a value for the parameter")}}],"plain-text")},[D]),xe=Ae((x,B)=>{if(a){a(x);return}if(!$&&!B?.bypassPro){H(true);return}if(x.type==="layout"||x.type==="group"){J.alert("Cannot Navigate",`${x.type==="layout"?"Layouts":"Route groups"} are not navigable routes`);return}if(x.type==="dynamic"||x.type==="catch-all"){if(x.params.length===0){try{D.push(x.path)}catch(Z){J.alert("Navigation Error",String(Z))}return}fe(x);return}try{D.push(x.path)}catch(Z){J.alert("Navigation Error",String(Z))}},[D,fe,$,a]),le=Ae(()=>{xe(wa,{bypassPro:true})},[xe]),v=Ae(()=>{p||(S(true),k(),setTimeout(()=>S(false),400))},[p,k]),F=Ke(()=>M?`Updated ${ua(M)}`:"Awaiting route data",[M]),U=Ke(()=>Q?`Source: ${Q}`:"Source: unknown",[Q]),ce=Ke(()=>i&&K.length>0?[{title:"Search Results",icon:"",routes:K}]:w,[i,K,w]);return te?z(c,{style:[s.container,e],children:[u&&z(c,{style:s.searchContainer,testID:"buoy-routes-sitemap-search-field",children:[m(Ht,{size:16,color:b.color.textTertiary}),m($t,{style:s.searchInput,placeholder:"Search routes...",placeholderTextColor:b.color.placeholder,value:i,onChangeText:n,autoCapitalize:"none",autoCorrect:false,autoFocus:true,testID:"buoy-routes-sitemap-search",accessibilityLabel:"Search routes"}),i.length>0&&m(V,{onPress:()=>n(""),style:s.clearButton,testID:"buoy-routes-sitemap-search-clear",accessibilityRole:"button",accessibilityLabel:"Clear route search",children:m(h,{style:s.clearButtonText,children:"\u2715"})}),m(V,{style:s.closeSearchButton,onPress:()=>{l(false),n("")},testID:"buoy-routes-sitemap-search-done",accessibilityRole:"button",accessibilityLabel:"Done searching routes",children:m(h,{style:s.closeSearchText,children:"Done"})})]}),z(Ue,{testID:"buoy-routes-sitemap-scroll",style:s.scrollView,contentContainerStyle:s.scrollContent,children:[!u&&z(c,{style:s.header,children:[z(c,{style:s.actionsRow,children:[z(c,{style:[s.actionWrapper,Y&&s.actionWrapperDesktop],children:[m(V,{style:[s.iconButton,Y&&s.iconButtonDesktop],onPress:le,accessibilityLabel:"Go to home route",accessibilityRole:"button",testID:"buoy-routes-sitemap-home",children:m(ia,{size:Je,color:b.color.textSecondary})}),m(h,{style:[s.actionLabel,Y&&s.actionLabelDesktop],children:"Home"})]}),z(c,{style:[s.actionWrapper,Y&&s.actionWrapperDesktop],children:[m(la,{value:A,testID:"buoy-routes-sitemap-copy",size:Y?Je:14,buttonStyle:Y?s.actionButtonHeaderDesktop:s.actionButtonHeader}),m(h,{style:[s.actionLabel,Y&&s.actionLabelDesktop],children:"Copy"})]}),z(c,{style:[s.actionWrapper,Y&&s.actionWrapperDesktop],children:[m(V,{style:[s.iconButton,Y&&s.iconButtonDesktop,p&&s.refreshButtonDisabled],onPress:v,disabled:p,testID:"buoy-routes-sitemap-refresh",accessibilityRole:"button",accessibilityLabel:"Refresh route tree",children:m(ca,{size:Je,color:p?b.color.textTertiary:b.color.textSecondary})}),m(h,{style:[s.actionLabel,Y&&s.actionLabelDesktop],children:"Refresh"})]}),z(c,{style:[s.actionWrapper,Y&&s.actionWrapperDesktop],children:[m(V,{style:[s.iconButton,Y&&s.iconButtonDesktop],onPress:()=>l(true),testID:"buoy-routes-sitemap-search-open",accessibilityRole:"button",accessibilityLabel:"Search routes",children:m(Ht,{size:Je,color:b.color.textSecondary})}),m(h,{style:[s.actionLabel,Y&&s.actionLabelDesktop],children:"Search"})]})]}),z(c,{style:s.statsGrid,children:[m(Ee,{value:R.total,label:"Total",id:"total"}),m(Ee,{value:R.static,label:"Static",id:"static"}),m(Ee,{value:R.dynamic,label:"Dynamic",id:"dynamic"}),m(Ee,{value:R.catchAll,label:"Catch-All",id:"catch-all"}),m(Ee,{value:R.layouts,label:"Layouts",id:"layouts"}),m(Ee,{value:R.groups,label:"Groups",id:"groups"})]})]}),ce.length===0?m(ra,{testID:"buoy-routes-sitemap-empty",otto:"map",title:"No routes found",message:"Nothing in the router matches. Clear the search to see the whole tree."}):ce.map(x=>m(Ia,{group:x,isExpanded:i.length>0||g.has(x.title),onToggleExpand:()=>Te(x.title),onNavigate:xe},x.title)),z(c,{style:s.metaFooter,children:[m(h,{style:s.metaText,testID:"buoy-routes-sitemap-updated",children:F}),m(c,{style:s.sourceBadge,children:m(h,{style:s.sourceText,testID:"buoy-routes-sitemap-source",children:U})})]})]}),m(da,{visible:L,onClose:()=>H(false),featureName:"Route Navigation"})]}):m(c,{style:[s.container,e],children:m(c,{style:s.loadingContainer,children:m(h,{style:s.loadingText,testID:"buoy-routes-sitemap-loading",children:E?"Loading routes...":"Route sitemap isn't available on the dashboard \u2014 the route tree lives on the device. Use the Events tab to see navigation here."})})})}function Ee({value:e,label:t,id:o}){return z(c,{style:s.statItem,testID:`buoy-routes-stat-${o}`,accessibilityLabel:`${t}, ${e}`,children:[m(h,{style:s.statValue,testID:`buoy-routes-stat-${o}-value`,children:e}),m(h,{style:s.statLabel,children:t})]})}function Ia({group:e,isExpanded:t,onToggleExpand:o,onNavigate:r}){return z(c,{style:s.groupContainer,children:[z(V,{style:s.groupHeader,onPress:o,activeOpacity:.7,testID:Kt(e.title),accessibilityRole:"button",accessibilityLabel:`${e.title}, ${e.routes.length} routes`,children:[z(c,{style:s.groupHeaderLeft,children:[t?m(Mt,{size:14,color:b.color.textSecondary}):m(Ut,{size:14,color:b.color.textSecondary}),m(h,{style:s.groupTitle,children:e.title})]}),m(c,{style:s.groupBadge,children:m(h,{style:s.groupCount,testID:`${Kt(e.title)}-count`,children:e.routes.length})})]}),e.description&&m(c,{style:s.groupDescription,children:m(h,{style:s.groupDescriptionText,children:e.description})}),t&&m(c,{style:s.routesList,children:e.routes.map((a,i)=>m(Qt,{route:a,onNavigate:r},`${a.path}-${i}`))})]})}function Qt({route:e,depth:t=0,onNavigate:o}){let[r,a]=Be(false),i=e.children.length>0,n=Ra(e.type),u=e.type!=="layout"&&e.type!=="group",l=Ta(e.path),g=i,d=g?r:true;return m(c,{style:[s.routeItem,{marginLeft:t*12}],testID:l,children:z(c,{style:s.routeCard,children:[z(c,{style:s.routeHeader,children:[g?z(V,{style:s.routeHeaderLeft,onPress:()=>a(!r),activeOpacity:.7,testID:`${l}-toggle`,accessibilityRole:"button",accessibilityLabel:`${e.path}, ${e.type}, ${e.children.length} nested`,children:[m(c,{style:s.expandIndicator,children:r?m(Mt,{size:14,color:b.color.textSecondary}):m(Ut,{size:14,color:b.color.textSecondary})}),m(h,{style:s.routePath,numberOfLines:3,testID:`${l}-path`,children:e.path})]}):z(c,{style:s.routeHeaderLeft,accessible:true,accessibilityLabel:`${e.path}, ${e.type}`,children:[m(c,{style:s.expandIndicator}),m(h,{style:s.routePath,numberOfLines:3,testID:`${l}-path`,children:e.path})]}),z(c,{style:s.routeHeaderActions,children:[i&&m(c,{style:s.childCountBadge,children:m(h,{style:s.childCountText,testID:`${l}-children-count`,children:e.children.length})}),m(c,{style:[s.typeTag,{backgroundColor:`${n}15`,borderColor:`${n}40`}],children:m(h,{style:[s.typeText,{color:n}],testID:`${l}-type`,children:e.type.toUpperCase()})}),m(sa,{value:e.path,buttonStyle:s.iconAction,testID:`${l}-copy`}),u&&m(V,{style:s.goButton,onPress:()=>o(e),activeOpacity:.7,testID:`${l}-go`,accessibilityRole:"button",accessibilityLabel:`Go to ${e.path}`,children:m(h,{style:s.goButtonText,children:"Go"})})]})]}),d&&i&&m(c,{style:s.childrenContainer,children:e.children.map((p,S)=>m(Qt,{route:p,depth:t+1,onNavigate:o},`${p.path}-${S}`))})]})})}function Ra(e){switch(e){case"static":return"#3B82F6";case"dynamic":return"#F59E0B";case"catch-all":return"#EC4899";case"index":return"#10B981";case"layout":return"#8B5CF6";case"group":return"#6366F1";case"not-found":return"#EF4444";default:return"#6B7280"}}var s=ve.create({container:{flex:1,backgroundColor:"transparent"},loadingContainer:{flex:1,justifyContent:"center",alignItems:"center"},loadingText:{color:b.color.textSecondary,fontSize:14,fontFamily:_,textAlign:"center",lineHeight:20,paddingHorizontal:32,maxWidth:420},header:{flexDirection:"column",padding:8,borderBottomWidth:1,borderBottomColor:b.color.border,gap:12,marginBottom:8},actionsRow:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",gap:12,paddingBottom:4},statsGrid:{flexDirection:"row",flexWrap:"wrap",gap:8},statItem:{flexGrow:1,flexShrink:1,flexBasis:"30%",minWidth:90,backgroundColor:b.color.surface,borderRadius:8,paddingVertical:10,paddingHorizontal:12,alignItems:"center"},statValue:{fontSize:18,fontWeight:"800",color:b.color.text,fontFamily:_},statLabel:{fontSize:10,color:b.color.textTertiary,marginTop:4,fontFamily:_,textTransform:"uppercase",letterSpacing:.5},actionWrapper:{flex:1,alignItems:"center",justifyContent:"center",gap:4,minWidth:48},actionWrapperDesktop:{gap:8,minWidth:72},actionButtonHeader:{padding:6,borderRadius:4,backgroundColor:b.color.surfaceElevated},actionButtonHeaderDesktop:{padding:12,borderRadius:8,backgroundColor:b.color.surfaceElevated},iconButton:{padding:6,borderRadius:4,alignItems:"center",justifyContent:"center"},iconButtonDesktop:{padding:12,borderRadius:8,backgroundColor:b.color.surfaceElevated},actionLabel:{fontSize:8,color:b.color.textTertiary,fontFamily:_,textTransform:"uppercase",letterSpacing:.5},actionLabelDesktop:{fontSize:12},refreshButtonDisabled:{opacity:.5},metaFooter:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",gap:8,paddingHorizontal:16,paddingVertical:16,marginTop:16,borderTopWidth:1,borderTopColor:b.color.border},metaText:{fontSize:12,color:b.color.textSecondary,fontFamily:_},sourceBadge:{paddingHorizontal:8,paddingVertical:2,borderRadius:999,borderWidth:1,borderColor:b.color.border,backgroundColor:b.color.surface},sourceText:{fontSize:11,color:b.color.textSecondary,textTransform:"capitalize",fontFamily:_},searchContainer:{flexDirection:"row",alignItems:"center",padding:8,gap:8,borderBottomWidth:1,borderBottomColor:b.color.border},searchInput:{flex:1,color:b.color.text,fontSize:14,fontFamily:_},clearButton:{padding:4},clearButtonText:{color:b.color.textTertiary,fontSize:18},closeSearchButton:{paddingHorizontal:8,paddingVertical:4},closeSearchText:{color:b.color.accent,fontSize:14,fontWeight:"600",fontFamily:_},scrollView:{flex:1},scrollContent:{paddingBottom:8},emptyState:{padding:32,alignItems:"center"},emptyText:{color:b.color.textSecondary,fontSize:14,fontFamily:_},groupContainer:{marginVertical:4},groupHeader:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",padding:12,paddingHorizontal:16,backgroundColor:b.color.surface,borderLeftWidth:3,borderLeftColor:b.color.fillTertiary},groupHeaderLeft:{flexDirection:"row",alignItems:"center",gap:8,flex:1},groupTitle:{fontSize:12,fontWeight:"700",color:b.color.text,fontFamily:_,textTransform:"uppercase",letterSpacing:.8},groupBadge:{backgroundColor:"#3B82F615",borderColor:"#3B82F640",borderWidth:1,borderRadius:12,paddingHorizontal:8,paddingVertical:3,minWidth:24,alignItems:"center",justifyContent:"center"},groupCount:{fontSize:11,fontWeight:"600",color:"#3B82F6",fontFamily:_},routesList:{backgroundColor:"transparent"},groupDescription:{paddingHorizontal:16,paddingVertical:8,marginBottom:8,backgroundColor:b.color.surfaceElevated,borderLeftWidth:3,borderLeftColor:b.color.fillTertiary},groupDescriptionText:{fontSize:11,color:b.color.textSecondary,fontFamily:_,lineHeight:16},routeItem:{marginBottom:6},routeCard:{backgroundColor:b.color.surface,borderRadius:6,borderWidth:1,borderColor:b.color.border,overflow:"hidden",shadowColor:"#000",shadowOffset:{width:0,height:1},shadowOpacity:.05,shadowRadius:2,elevation:1},routeHeader:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",paddingVertical:7,paddingHorizontal:10,gap:8},expandIndicator:{width:18,alignItems:"center"},routeHeaderLeft:{flexDirection:"row",alignItems:"center",gap:8,flex:1},routePath:{fontSize:13,fontWeight:"600",color:b.color.text,fontFamily:_,flex:1},routeHeaderActions:{flexDirection:"row",alignItems:"center",gap:6},childCountBadge:{backgroundColor:"#6B728015",borderColor:"#6B728040",borderWidth:1,borderRadius:12,paddingHorizontal:7,paddingVertical:2,minWidth:22,alignItems:"center",justifyContent:"center"},childCountText:{fontSize:11,fontWeight:"600",color:b.color.textSecondary,fontFamily:_},typeTag:{borderRadius:4,paddingHorizontal:6,paddingVertical:2,borderWidth:1},typeText:{fontSize:10,fontWeight:"600",fontFamily:_},iconAction:{width:28,height:24,borderRadius:4,backgroundColor:b.color.surfaceElevated,borderWidth:1,borderColor:b.color.border,alignItems:"center",justifyContent:"center"},goButton:{height:24,paddingHorizontal:10,borderRadius:4,alignItems:"center",justifyContent:"center",backgroundColor:b.color.accentSoft,borderWidth:1,borderColor:b.color.accentBorder},goButtonText:{fontSize:12,color:b.color.accent,fontFamily:_,fontWeight:"600"},childrenContainer:{borderLeftWidth:2,borderLeftColor:b.color.border,marginLeft:16,marginRight:8,marginTop:2,marginBottom:8}});import{useState as Jt,useMemo as qe,useEffect as qt}from"react";import{ChevronDown as ka,ChevronRight as Ba,InlineCopyButton as Da,ProUpgradeModal as Ea,buoyColors as Xe,night as O,useSafeAreaInsets as Pa,ToolEmptyState as La,monoFont as se}from"@buoy-gg/shared-ui/web";import{useIsPro as $a}from"@buoy-gg/license/web";import{DataViewer as Fa}from"@buoy-gg/shared-ui/web/dataViewer";import{useSyncExternalStore as za}from"react";var Na=class{constructor(){this.stack=[];this.actions=null;this.listeners=new Set}getStack(){return this.stack}setStack(e){this.stack=e,this.listeners.forEach(t=>t())}getActions(){return this.actions}setActions(e){this.actions=e}subscribe(e){return this.listeners.add(e),()=>{this.listeners.delete(e)}}},W=new Na;var Aa=[];function Xt(){let e=za(r=>W.subscribe(r),()=>W.getStack(),()=>Aa),t=e.find(r=>r.isFocused)??null,o=()=>{let r=W.getActions();if(!r)throw new Error("Mount RouteTracker to capture browser navigation.");return r};return{stack:e,focusedRoute:t,stackDepth:e.length,isAtRoot:!t||t.index===0,isLoaded:e.length>0,error:null,refresh:()=>{},navigateToIndex:r=>o().navigateToIndex(r),navigateToRoute:(r,a)=>o().navigateToRoute?.(r,a)??false,popToIndex:r=>o().popToIndex(r),goBack:()=>o().goBack(),popToTop:()=>o().popToTop()}}import{jsx as I,jsxs as re}from"react/jsx-runtime";function Yt({style:e,injectedStack:t,onAction:o,onCopyValueChange:r}){let a=Xt(),i=t!=null,n=Pa({minBottom:8}),u=i?t:a.stack,l=i?true:a.isLoaded,g=i?null:a.error,d=qe(()=>u.find(v=>v.isFocused)??null,[u]),p=u.length,S=p<=1,L=v=>o?o("navigateToIndex",{index:v}):a.navigateToIndex(v),H=v=>o?o("popToIndex",{index:v}):a.popToIndex(v),$=()=>o?o("goBack"):a.goBack(),D=()=>o?o("popToTop"):a.popToTop(),[w,R]=Jt(null),[te,E]=Jt(false),K=$a();qt(()=>{te&&K&&E(false)},[te,K]);let pe=qe(()=>{let v=u.map(F=>({pathname:F.pathname,name:F.name,params:F.params,isFocused:F.isFocused}));return JSON.stringify(v,null,2)},[u]);qt(()=>{r?.(pe)},[pe,r]);let k=qe(()=>w!==null&&u[w]?u[w]:d,[w,u,d]),M=qe(()=>w!==null&&u[w]&&!u[w].isFocused,[w,u]);if(!l)return I(c,{style:[f.container,e],children:I(c,{style:f.loadingContainer,children:I(h,{style:f.loadingText,testID:"buoy-routes-stack-loading",children:"Loading navigation stack..."})})});if(g)return I(c,{style:[f.container,e],children:re(c,{style:f.errorContainer,testID:"buoy-routes-stack-error",children:[I(h,{style:f.errorText,children:"Error loading stack"}),I(h,{style:f.errorDetail,testID:"buoy-routes-stack-error-detail",children:g.message})]})});if(u.length===0)return I(c,{style:[f.container,e],children:I(La,{testID:"buoy-routes-stack-empty",otto:"walking",title:"No navigation stack",message:"Navigate to a route to see the stack"})});let Q=(v,F,U,ce)=>{if(o){let x=globalThis.window?.confirm;(!x||x(`${v}
|
|
4
|
+
Route: ${x.path}`,rt=W=>{W&&W.trim()&&ce(x,R+1,{...Y,[Te]:W.trim()})};if(typeof M.prompt!="function"){let W=globalThis.prompt;W?rt(W(`${$e}
|
|
5
5
|
|
|
6
|
-
${F}`))&&ce();return}J.alert(v,F,[{text:"Cancel",style:"cancel"},{text:U,style:"destructive",onPress:ce}])},A=()=>{if(!K){E(true);return}if(S){J.alert("Cannot Go Back","Already at the root of the stack");return}$()},Te=()=>{if(!K){E(true);return}if(S){J.alert("Already at Top","Stack only has one screen");return}Q("Pop to Top","This will remove all screens except the root screen.","Pop to Top",D)},fe=v=>{R(w===v?null:v)},xe=()=>{if(!K){E(true);return}if(k){if(k.isFocused){J.alert("Already There","This route is already visible");return}L(k.index)}},le=()=>{if(!K){E(true);return}if(!k)return;if(k.isFocused){J.alert("Cannot Pop","Selected route is already visible");return}if(k.index===p-1){J.alert("Cannot Pop","No screens above selected route");return}let v=p-1-k.index,F=k.index;Q("Pop to Route",`Remove ${v} screen${v!==1?"s":""} above ${k.pathname}?`,"Pop",()=>H(F))};return re(c,{style:[f.container,e],children:[I(Ue,{testID:"buoy-routes-stack-scroll",style:f.stackScroll,contentContainerStyle:[f.stackContent,{paddingBottom:f.stackContent.padding+n.bottom}],children:[...u].reverse().map((v,F)=>{let U=u.length-1-F,ce=w===U,x=Object.keys(v.params).length>0,B=Ca(U);return I(c,{style:f.stackItemWrapper,testID:B,children:re(c,{style:[f.stackItem,ce&&f.stackItemSelected],children:[re(V,{style:f.stackItemHeader,onPress:()=>fe(U),activeOpacity:.7,testID:`${B}-toggle`,accessibilityRole:"button",accessibilityLabel:`${v.pathname}, ${v.isFocused?"focused":"mounted"}, position ${U} of ${p-1}`,children:[I(c,{style:f.expandIndicator,children:ce?I(ka,{size:14,color:O.color.textSecondary}):I(Ba,{size:14,color:O.color.textSecondary})}),I(h,{style:f.stackItemPath,numberOfLines:1,testID:`${B}-path`,children:v.pathname}),I(Da,{value:v.pathname,buttonStyle:f.copyRouteButton,testID:`${B}-copy`}),I(c,{style:[f.statusBadge,{backgroundColor:v.isFocused?`${Xe.success}15`:"#3B82F615",borderColor:v.isFocused?`${Xe.success}40`:"#3B82F640"}],children:I(h,{style:[f.statusBadgeText,{color:v.isFocused?Xe.success:"#3B82F6"}],testID:`${B}-status`,children:v.isFocused?"FOCUSED":"MOUNTED"})})]}),ce&&re(c,{style:f.expandedContent,children:[re(c,{style:f.detailRow,children:[I(h,{style:f.detailLabel,children:"Route Name:"}),I(h,{style:f.detailValue,testID:`${B}-name`,children:v.name})]}),re(c,{style:f.detailRow,children:[I(h,{style:f.detailLabel,children:"Position:"}),re(h,{style:f.detailValue,testID:`${B}-position`,children:[U," / ",p-1]})]}),x&&I(c,{style:f.dataViewerContainer,children:I(Fa,{title:"Parameters",data:v.params,showTypeFilter:false})}),re(c,{style:f.actionsRow,children:[re(c,{style:f.actionWrapper,children:[I(V,{style:[f.actionButton,S&&f.actionButtonDisabled],onPress:A,disabled:S,testID:`${B}-back`,accessibilityRole:"button",accessibilityLabel:"Go back one screen",children:I(h,{style:[f.actionButtonText,S&&f.actionButtonTextDisabled],children:"Back"})}),I(h,{style:f.helpText,children:"Go back one screen"})]}),re(c,{style:f.actionWrapper,children:[I(V,{style:[f.actionButton,v.isFocused&&f.actionButtonDisabled],onPress:xe,disabled:v.isFocused,testID:`${B}-go`,accessibilityRole:"button",accessibilityLabel:`Navigate to ${v.pathname}`,children:I(h,{style:[f.actionButtonText,v.isFocused&&f.actionButtonTextDisabled],children:"Go"})}),I(h,{style:f.helpText,children:"Navigate to this route"})]}),re(c,{style:f.actionWrapper,children:[I(V,{style:[f.actionButton,(v.isFocused||U===p-1)&&f.actionButtonDisabled],onPress:le,disabled:v.isFocused||U===p-1,testID:`${B}-pop-to`,accessibilityRole:"button",accessibilityLabel:`Remove screens above ${v.pathname}`,children:I(h,{style:[f.actionButtonText,(v.isFocused||U===p-1)&&f.actionButtonTextDisabled],children:"Pop To"})}),I(h,{style:f.helpText,children:"Remove screens above this"})]})]})]})]})},`stack-${U}-${v.key}`)})}),I(Ea,{visible:te,onClose:()=>E(false),featureName:"Stack Navigation"})]})}var f=ve.create({container:{flex:1,backgroundColor:"transparent"},loadingContainer:{flex:1,justifyContent:"center",alignItems:"center",padding:32},loadingText:{color:O.color.textSecondary,fontSize:14,fontFamily:se},errorContainer:{flex:1,justifyContent:"center",alignItems:"center",padding:32},errorText:{color:Xe.error,fontSize:16,fontWeight:"600",fontFamily:se,marginBottom:8},errorDetail:{color:O.color.textSecondary,fontSize:12,fontFamily:se,textAlign:"center"},emptyContainer:{flex:1,justifyContent:"center",alignItems:"center",padding:32},emptyText:{color:O.color.text,fontSize:16,fontWeight:"600",fontFamily:se,marginBottom:8},emptySubtext:{color:O.color.textSecondary,fontSize:14,fontFamily:se,textAlign:"center"},stackScroll:{flex:1},stackContent:{padding:8},stackItemWrapper:{marginBottom:6},stackItem:{backgroundColor:O.color.surface,borderRadius:6,borderWidth:1,borderColor:O.color.border,overflow:"hidden"},stackItemSelected:{borderColor:O.color.accent,borderWidth:2},stackItemHeader:{flexDirection:"row",alignItems:"center",paddingVertical:10,paddingHorizontal:12,gap:8},expandIndicator:{width:20,alignItems:"center"},stackItemPath:{fontSize:13,fontWeight:"600",color:O.color.text,fontFamily:se,flex:1},copyRouteButton:{padding:4,marginLeft:4},statusBadge:{borderRadius:4,paddingHorizontal:6,paddingVertical:2,borderWidth:1},statusBadgeText:{fontSize:10,fontWeight:"600",fontFamily:se},expandedContent:{paddingHorizontal:12,paddingTop:8,paddingBottom:12,borderTopWidth:1,borderTopColor:O.color.border},detailRow:{marginBottom:8},detailLabel:{fontSize:10,color:O.color.textSecondary,fontFamily:se,marginBottom:2},detailValue:{fontSize:12,color:O.color.text,fontFamily:se},dataViewerContainer:{marginTop:4,marginHorizontal:-12,marginBottom:8},actionsRow:{flexDirection:"row",gap:6,marginTop:12},actionWrapper:{flex:1},actionButton:{backgroundColor:O.color.surfaceElevated,paddingVertical:8,paddingHorizontal:8,borderRadius:6,alignItems:"center"},actionButtonDisabled:{opacity:.5},actionButtonText:{fontSize:12,fontWeight:"600",color:O.color.text,fontFamily:se},actionButtonTextDisabled:{color:O.color.textTertiary},helpText:{fontSize:9,color:O.color.textSecondary,fontFamily:se,textAlign:"center",marginTop:4,lineHeight:12}});import{useCallback as Wa}from"react";import{Navigation as ja,night as yt,EVENT_LIST_PRESET as Va,monoFont as Zt}from"@buoy-gg/shared-ui/web";import{memo as Oa,useMemo as de}from"react";import{CompactRow as Ha,RelativeTime as Ma,buoyColors as eo,night as Ye,monoFont as to}from"@buoy-gg/shared-ui/web";import{jsx as je}from"react/jsx-runtime";function Ua(e){return e.pathname==="/"?"home":ut(e.pathname,e.segments)?"dynamic":e.params&&Object.keys(e.params).length>0?"with-params":"default"}function Ga(e){switch(e){case"home":return eo.success;case"dynamic":return Ye.color.accent;case"with-params":return eo.warning;default:return Ye.color.textSecondary}}function _a(e){switch(e){case"home":return"Home";case"dynamic":return"Dynamic";case"with-params":return"Params";default:return"Static"}}function Ka(e){if(e<1e3)return`${Math.round(e)}ms`;if(e<6e4)return`${(e/1e3).toFixed(1)}s`;let t=Math.floor(e/6e4),o=Math.floor(e%6e4/1e3);return o>0?`${t}m ${o}s`:`${t}m`}function Qa(e){let t=[];e.timeSincePrevious!==void 0&&e.timeSincePrevious>0&&t.push(Ka(e.timeSincePrevious));let o=e.segments?.length||0;return o>0&&t.push(`depth ${o}`),t.join(" \xB7 ")||"root"}function Ja(e){if(e.params&&Object.keys(e.params).length>0){let t=Object.keys(e.params).length;return`${t} PARAM${t!==1?"S":""}`}}var oo=Oa(function({event:e,visitNumber:t,isExpanded:o,onPress:r,onNavigate:a,index:i}){let n=de(()=>Ua(e),[e]),u=de(()=>ut(e.pathname,e.segments),[e.pathname,e.segments]),l=de(()=>Ga(n),[n]),g=de(()=>_a(n),[n]),d=de(()=>Qa(e),[e]),p=de(()=>Ja(e),[e]),S=de(()=>Sa(e.pathname,t),[e.pathname,t]),L=de(()=>`${e.pathname}, ${g}, ${d}`,[e.pathname,g,d]),H=de(()=>{if(o)return je(ct,{event:e,visitNumber:t,routeTemplate:u})},[o,e,t,u]),$=de(()=>{if(a)return je(V,{style:ro.goButton,onPress:()=>a(Wt(e.pathname,e.params)),testID:`${S}-go`,accessibilityRole:"button",accessibilityLabel:`Go to ${e.pathname}`,children:je(h,{style:ro.goButtonText,children:"Go"})})},[a,e.pathname,S]);return je(Ha,{statusDotColor:l,statusLabel:g,statusSublabel:d,primaryText:e.pathname,badgeText:p,badgeColor:l,trailingAction:$,bottomRightText:je(Ma,{timestamp:e.timestamp}),showChevron:true,expandedContent:H,isExpanded:o,expandedGlowColor:l,onPress:()=>r(i),testID:S,statusTestID:`${S}-status`,statusSublabelTestID:`${S}-sublabel`,accessibilityLabel:L})}),ro=ve.create({badgeText:{fontSize:11,fontWeight:"600",fontFamily:to},goButton:{backgroundColor:Ye.color.accent,paddingHorizontal:8,paddingVertical:4,borderRadius:4},goButtonText:{fontSize:10,fontWeight:"600",color:Ye.color.onAccent,fontFamily:to}});import{jsx as Ve,jsxs as qa}from"react/jsx-runtime";function Xa({events:e,visitCounts:t,onNavigate:o,onSelectEvent:r}){let a=Wa(i=>{let n=e[i];n&&r(n,t.get(n)||1)},[e,t,r]);return e.length===0?qa(c,{style:Ze.emptyState,testID:"buoy-routes-empty",children:[Ve(ja,{size:48,color:yt.color.textTertiary}),Ve(h,{style:Ze.emptyTitle,testID:"buoy-routes-empty-title",children:"No events yet"}),Ve(h,{style:Ze.emptySubtitle,testID:"buoy-routes-empty-subtitle",children:"Navigation events will appear here"})]}):Ve(Lt,{testID:"buoy-routes-timeline",contentContainerStyle:Ze.listContent,data:e,keyExtractor:i=>`${i.timestamp}-${i.pathname}`,renderItem:({item:i,index:n})=>Ve(oo,{event:i,visitNumber:t.get(i)||1,isExpanded:false,index:n,onPress:a,onNavigate:o}),showsVerticalScrollIndicator:true,...Va})}var Ze=ve.create({listContent:{paddingVertical:8},emptyState:{flex:1,justifyContent:"center",alignItems:"center",padding:32},emptyTitle:{color:yt.color.text,fontSize:16,fontWeight:"600",marginTop:16,marginBottom:8,fontFamily:Zt,letterSpacing:.5,textTransform:"uppercase"},emptySubtitle:{color:yt.color.textSecondary,fontSize:14,textAlign:"center",fontFamily:Zt}});import{Fragment as Ya,jsx as C,jsxs as ae}from"react/jsx-runtime";var bt=Rr(),Za={parse:e=>e==="routes"||e==="events"||e==="stack"?e:void 0,serialize:e=>e},en={parse:e=>e==="true",serialize:e=>e.toString()},tn={parse:e=>new Set(JSON.parse(e)),serialize:e=>JSON.stringify(Array.from(e))};function ao(e,t){if(!e||!e.routes)return null;for(let o of e.routes){if(o.name===t)return[o.name];if(o.state){let r=ao(o.state,t);if(r)return[o.name,...r]}}return null}function on(e,t){if(e.length===0)return null;let o=t&&Object.keys(t).length>0?t:void 0;if(e.length===1)return bt.navigate(o?{name:e[0],params:o}:{name:e[0]});let r=o?{screen:e[e.length-1],params:o}:{screen:e[e.length-1]};for(let a=e.length-2;a>=1;a--)r={screen:e[a],params:r};return bt.navigate({name:e[0],params:r})}function vt({visible:e,onClose:t,onBack:o,onMinimize:r,enableSharedModalDimensions:a=false,inline:i=false,remote:n}){let u=kr(),l=void 0,g=at.OS==="web"||Br(),[d,p]=nt($e.routeEvents.activeTab(),"events",Za),[S,L]=Ie(false),[H,$]=Ie(""),D=Hr(),w=Or("routeEvents.entries");Et(()=>{S&&D&&L(false)},[S,D]);let[R,te]=nt($e.routeEvents.isMonitoring(),true,en),{events:E,clearEvents:K,isListening:pe}=At({enabled:R}),k=R&&pe;Et(()=>{he.setBootCapture(R)},[R]);let[M,Q]=Ie(false),[A,Te]=Ie(null),[fe,xe]=Ie(1),[le,v]=Ie(""),[F,U]=nt($e.routeEvents.eventFilters(),new Set(["/_sitemap","/api","/__dev"]),tn),ce=ko(null),x=ue(y=>{},[]),B=ue(y=>{try{if(n){if(!n.onNavigatePath)return;if(!D&&y!=="/"){L(true);return}n.onNavigatePath(y);return}if(g)u.push(y);else if(l){let{pathname:P,params:X}=Yr(y),me=P.startsWith("/")?P.slice(1):P,Ce=Object.keys(X).length>0,we=l.getRootState?.();if(we){let Me=ao(we,me);if(Me){let kt=on(Me,X);if(kt){l.dispatch(kt);return}}}l.dispatch(bt.navigate(Ce?{name:me,params:X}:{name:me}))}else J.alert("Navigation Unavailable","No Expo Router or React Navigation container was found in this app.")}catch(P){J.alert("Navigation Error",String(P))}},[u,l,g,n,D]),Z=ue(()=>{te(y=>!y)},[]),Pe=ue(()=>{if(E.length!==0){if(!D){L(true);return}K()}},[E.length,D,K]),Le=ue(y=>{U(P=>{let X=new Set(P);return X.has(y)?X.delete(y):X.add(y),X})},[]),et=ue(y=>{U(P=>new Set([...P,y]))},[]),ne=ue(()=>{Q(!M)},[M]),ye=ue((y,P)=>{Te(y),xe(P)},[]),He=ue(()=>{Te(null)},[]),go=ue(y=>{Te(null),p(y)},[]),fo=Re(()=>{let y=new Set;return E.forEach(P=>{P.pathname&&y.add(P.pathname)}),Array.from(y).sort()},[E]),be=Re(()=>E.filter(y=>{if(!y.pathname||Array.from(F).some(P=>y.pathname.includes(P)))return false;if(le.trim()){let P=le.toLowerCase(),X=y.pathname.toLowerCase().includes(P),me=Object.entries(y.params||{}).some(([Ce,we])=>{let Me=Array.isArray(we)?we.join(" "):we;return Ce.toLowerCase().includes(P)||Me.toLowerCase().includes(P)});return X||me}return true}),[E,F,le]),yo=Re(()=>be.slice(0,w),[be,w]),tt=Re(()=>Math.max(0,be.length-w),[be.length,w]),ot=Re(()=>{let y=new Map,P=new Map;for(let X=E.length-1;X>=0;X--){let me=E[X],Ce=(y.get(me.pathname)||0)+1;y.set(me.pathname,Ce),P.set(me,Ce)}return P},[E]),bo=Re(()=>({summary:{total:E.length,filtered:be.length,listening:k,ignoredPatterns:Array.from(F),timestamp:new Date().toISOString()},events:be.map((y,P)=>({index:P,visitNumber:ot.get(y)||1,pathname:y.pathname,timestamp:y.timestamp,timestampRelative:Fr(y.timestamp),params:y.params,segments:y.segments,previousPathname:y.previousPathname,timeSincePrevious:y.timeSincePrevious}))}),[E.length,be,k,F,ot]);if(!e)return null;let vo=a?$e.modal.root():$e.routeEvents.modal(),rt=null,wt=()=>{if(A)return C(Vt,{event:A,visitNumber:fe,onNavigate:B});if(d==="routes")return g||n?.sitemap?C(ft,{style:j.contentWrapper,injectedRoutes:n?.sitemap?.routes,injectedSource:n?.sitemap?.source??null,injectedLastUpdatedAt:n?.sitemap?.lastUpdatedAt??null,onNavigateRoute:n?xo:void 0}):C(ft,{style:j.contentWrapper});if(d==="stack")return C(Yt,{style:j.contentWrapper,injectedStack:n?n.stack??[]:void 0,onAction:n?.onStackAction,onCopyValueChange:$});if(M)return C(ta,{ignoredPatterns:F,onTogglePattern:Le,onAddPattern:et,availablePathnames:fo});let y=E.length>0;return be.length===0?ae(c,{style:j.contentWrapper,testID:"buoy-routes-events",children:[y&&C(c,{style:j.searchContainer,testID:"buoy-routes-search-field",children:C(Ft,{value:le,onChange:v,placeholder:"Search pathname or params...",testID:"buoy-routes-search"})}),C(Er,{testID:"buoy-routes-empty",...Pr({subject:"route events",search:le,total:E.length,capturing:k,waiting:{otto:"walking",title:"No route events yet",message:"Navigation events will appear here"},paused:{title:"Event listener is paused",message:"Press play to start monitoring"}})})]}):ae(c,{style:j.contentWrapper,testID:"buoy-routes-events",children:[C(c,{style:j.searchContainer,testID:"buoy-routes-search-field",children:C(Ft,{value:le,onChange:v,placeholder:"Search pathname or params...",testID:"buoy-routes-search"})}),tt>0&&ae(c,{style:j.lockedEventsBanner,testID:"buoy-routes-locked-banner",children:[C(Ar,{size:14,color:G.color.warning}),ae(h,{style:j.lockedEventsBannerText,testID:"buoy-routes-locked-banner-text",children:[tt," older ",tt===1?"event":"events"," locked"]}),C(h,{style:j.lockedEventsBannerSubtext,children:"Upgrade to Pro for full history"})]}),C(Xa,{events:yo,visitCounts:ot,onNavigate:B,onSelectEvent:ye})]})},It=A?ae(ie,{children:[C(ie.Navigation,{onBack:He}),C(ie.Content,{title:A.pathname,testID:"buoy-routes-detail-title"}),C(ie.Actions,{children:C(it,{testID:"buoy-routes-detail-copy",value:{pathname:A.pathname,previousPathname:A.previousPathname,params:A.params,segments:A.segments,timestamp:A.timestamp,timestampISO:new Date(A.timestamp).toISOString(),timeSincePrevious:A.timeSincePrevious,visitNumber:fe},buttonStyle:j.iconButton})})]}):M?ae(ie,{children:[C(ie.Navigation,{onBack:()=>Q(false)}),C(ie.Content,{title:"Filters",testID:"buoy-routes-filters-title"})]}):ae(ie,{children:[o&&C(ie.Navigation,{onBack:o}),C(ie.Content,{title:"",noMargin:true,children:C($r,{tabs:[{key:"routes",label:g?"Routes":"Screens"},{key:"events",label:`Events${E.length>0&&d!=="events"?` (${E.length})`:""}`},{key:"stack",label:"Stack"}],activeTab:d,onTabChange:y=>go(y),testIDPrefix:"buoy-routes-tab"})}),ae(ie.Actions,{children:[d==="stack"&&C(it,{value:H,buttonStyle:j.iconButton,testID:"buoy-routes-stack-copy"}),d==="events"&&ae(Ya,{children:[C(it,{value:bo,buttonStyle:j.iconButton,testID:"buoy-routes-copy"}),C(V,{onPress:ne,style:[j.iconButton,F.size>0&&j.activeFilterButton],testID:"buoy-routes-filters",accessibilityRole:"button",accessibilityLabel:F.size>0?`Route filters, ${F.size} active`:"Route filters",children:C(Nr,{size:14,color:F.size>0?G.color.accent:G.color.textSecondary})}),C(jr,{isEnabled:k,onToggle:Z,accessibilityLabel:"Toggle route event monitoring",testID:"buoy-routes-power"}),C(V,{onPress:Pe,style:j.iconButton,testID:"buoy-routes-clear",accessibilityRole:"button",accessibilityLabel:"Clear route events",children:C(zr,{size:14,color:G.color.danger})})]})]})]}),xo=y=>{if(y.type==="layout"||y.type==="group")return;let P=y.type==="index"||y.path==="/";if(!D&&!P){L(true);return}n?.onNavigateRoute?.(y)},Rt=C(Wr,{visible:S,onClose:()=>L(false),featureName:"Route Event Management"});return i?ae(zt,{children:[ae(c,{style:j.inlineRoot,children:[C(c,{style:j.inlineHeader,...Dr,children:It}),wt(),rt]}),Rt]}):C(zt,{children:ae(Lr,{visible:e,onClose:t,onMinimize:r,persistenceKey:vo,header:{showToggleButton:true,customContent:It},onModeChange:x,enablePersistence:true,initialMode:"bottomSheet",enableGlitchEffects:true,disableScrollWrapper:true,styles:{},footer:rt,footerHeight:rt?68:0,children:[wt(),Rt]})})}function rn(e={}){return C(vt,{...e,inline:true,visible:true,onClose:()=>{}})}var j=ve.create({inlineRoot:{flex:1,minHeight:0,backgroundColor:"transparent"},inlineHeader:{paddingHorizontal:12,paddingVertical:8,borderBottomWidth:1,borderBottomColor:Vr.border,backgroundColor:"transparent"},iconButton:{padding:6,borderRadius:6,backgroundColor:G.color.buttonSurface},activeFilterButton:{backgroundColor:G.color.accentSoft},emptyState:{flex:1,justifyContent:"center",alignItems:"center",padding:32},emptyTitle:{color:G.color.text,fontSize:16,fontWeight:"600",marginTop:16,marginBottom:8,fontFamily:Ge,letterSpacing:.5,textTransform:"uppercase"},emptySubtitle:{color:G.color.textSecondary,fontSize:14,textAlign:"center",fontFamily:Ge},contentWrapper:{flex:1},statsContainer:{paddingHorizontal:16,paddingVertical:8,backgroundColor:G.color.surface,borderBottomWidth:1,borderBottomColor:G.color.border},statsText:{fontSize:11,color:G.color.textSecondary,fontFamily:Ge,textAlign:"center"},statsWarning:{color:G.color.warning,fontWeight:"600"},searchContainer:{paddingHorizontal:16,paddingVertical:8,backgroundColor:"transparent"},lockedEventsBanner:{flexDirection:"row",alignItems:"center",gap:8,backgroundColor:G.color.warningSoft,borderWidth:1,borderColor:G.color.warning+"30",borderRadius:8,paddingVertical:10,paddingHorizontal:14,marginHorizontal:16,marginBottom:8},lockedEventsBannerText:{fontSize:12,fontWeight:"600",color:G.color.warning,fontFamily:Ge},lockedEventsBannerSubtext:{fontSize:11,color:G.color.textSecondary,marginLeft:"auto"}});import{createToolFactory as an,defineToolPreset as nn}from"@buoy-gg/shared-ui/web";import{jsx as sn}from"react/jsx-runtime";var no=nn({id:"route-events",name:"ROUTES",description:"Route tracking & navigation inspector",slot:"both",icon:({size:e})=>sn(Ro,{size:e}),component:vt,props:{enableSharedModalDimensions:false}}),ln=an(no,e=>({enableSharedModalDimensions:e.enableSharedModalDimensions??false}));import{useEffect as cn}from"react";import{browserRouter as io,getBrowserHref as un,getBrowserRouteURL as so,subscribeBrowserNavigation as dn}from"@buoy-gg/shared-ui/web/utils";var lo=0,xt;function pn(){if(typeof window>"u")return()=>{};if(lo++===0){he.hydrateBootCapture();let t,o,r="",a=[],i=-1,n=()=>{let d=window.history.state;if(!d||typeof d!="object")return;let p=d.key??d.__TSR_key;return typeof p=="string"||typeof p=="number"?String(p):void 0},u=d=>{for(let p=i-1;p>=0;p--)if(a[p].href===d)return p;for(let p=i+1;p<a.length;p++)if(a[p].href===d)return p;return-1},l=d=>{let p=n();if(d.href===r&&d.kind==="pop"&&(p===void 0||a[i]?.key===p))return;if(d.kind==="replace"&&i>=0)a[i]={href:d.href,key:p};else if(d.kind==="pop"){let $=p===void 0?-1:a.findIndex(w=>w.key===p),D=$>=0?$:u(d.href);D>=0?i=D:(a.splice(i+1),a.push({href:d.href,key:p}),i++)}else a.splice(i+1),a.push({href:d.href,key:p}),i++;r=d.href;let S=so(d.href),L=Date.now(),H=_t(S.pathname);Fe.emit({pathname:S.pathname,params:{...H.params,...Object.fromEntries(S.searchParams)},segments:H.segments,previousPathname:t,timestamp:L,timeSincePrevious:o===void 0?void 0:L-o}),t=S.pathname,o=L,W.setStack(a.slice(0,i+1).map(({href:$},D)=>{let w=so($),R=_t(w.pathname);return{key:`browser:${D}`,name:R.segments.join("/")||"index",pathname:w.pathname,params:{...R.params,...Object.fromEntries(w.searchParams)},index:D,isFocused:D===i,canPop:D>0}}))},g=d=>{if(!Number.isInteger(d)||d<0||d>=a.length)throw new Error("That browser history entry is unavailable.");window.history.go(d-i)};W.setActions({navigateToIndex:g,popToIndex:g,goBack:io.back,popToTop:()=>g(0),navigateToRoute:(d,p)=>{let S={...p},L=`/${d.replace(/^\//,"")}`.replace(/\[(\.\.\.)?([^\]]+)\]/g,(H,$,D)=>{if(!(D in S))return H;let w=S[D];return delete S[D],$&&Array.isArray(w)?w.map(R=>encodeURIComponent(String(R))).join("/"):encodeURIComponent(String(w))});return io.push({pathname:L==="/index"?"/":L,params:S}),true}}),xt=dn(l),l({href:un(),kind:"initial"})}let e=false;return()=>{e||(e=true,--lo===0&&(xt?.(),xt=void 0,W.setActions(null)))}}function mn(){return cn(pn,[]),null}import{useEffect as co,useRef as St}from"react";import{useSafePathname as hn,useSafeSegments as gn,useSafeGlobalSearchParams as fn}from"@buoy-gg/shared-ui/web";function yn(e){let t=hn(),o=gn(),r=fn(),a=St(e),i=St(void 0),n=St(void 0);co(()=>{a.current=e},[e]),co(()=>{let u=Date.now(),l=n.current?u-n.current:void 0,g={pathname:t,params:r,segments:o,timestamp:u,previousPathname:i.current,timeSincePrevious:l};i.current=t,n.current=u,Fe.emit(g),a.current&&a.current(g)},[t,o,r])}import{useEffect as uo,useRef as Tt}from"react";function po(e){if(!e||!e.routes||e.routes.length===0)return{route:null,segments:[]};let t=e.routes[e.index??0],o=[t.name];if(t.state){let r=po(t.state);if(r.route)return{route:r.route,segments:[...o,...r.segments]}}return{route:t,segments:o}}function mo(e,t,o,r){if(!e)return;let{route:a,segments:i}=po(e);if(!a)return;let n=`/${a.name}`;if(n===t.current)return;let u=Date.now(),l=o.current?u-o.current:void 0,g={pathname:n,params:a.params||{},segments:i,timestamp:u,previousPathname:t.current,timeSincePrevious:l};t.current=n,o.current=u,Fe.emit(g),r.current&&r.current(g)}function bn(e){let t=void 0,o=Tt(e),r=Tt(void 0),a=Tt(void 0);uo(()=>{o.current=e},[e]),uo(()=>{if(!t)return;let i=t.getRootState?.();i&&mo(i,r,a,o);let n=t.addListener?.("state",()=>{let u=t.getRootState?.();mo(u,r,a,o)});return()=>{n?.()}},[t])}import{getSafeRouter as vn}from"@buoy-gg/shared-ui/web";function xn(e,t){let o=[],r=false,a=u=>{for(let l of u??[])(l.name?.includes("+not-found")||l.path?.includes("+not-found"))&&(r=true),typeof l.path=="string"&&o.push(l.path),a(l.children)};if(a(t),r||o.length===0)return;let i=u=>"/"+u.split("?")[0].split("#")[0].split("/").filter(l=>l&&!/^\(.*\)$/.test(l)).join("/"),n=i(e);return o.some(u=>{let l=i(u);return l===n?true:new RegExp("^"+l.split("/").map(g=>/^\[\.\.\..+\]$/.test(g)?".+":/^\[.+\]$/.test(g)?"[^/]+":g.replace(/[.*+?^${}()|\\]/g,"\\$&")).join("/")+"$").test(n)})}import{isOverWireBudget as Sn}from"@buoy-gg/shared-ui/web";async function Tn(e,t){let o=W.getStack().findIndex(a=>a.isFocused),r=W.getActions();if(o<0||!r||typeof e.replace!="function")throw new Error("This app's history isn't captured yet, so Buoy can't start over. Open the Routes tool once, or navigate without reset.");if(o>0){let a=globalThis;await new Promise((i,n)=>{let u=d=>{clearTimeout(g),a.removeEventListener?.("popstate",l),d?i():n(new Error("The app didn't go back to its first page, so nothing was reset. Try again, or navigate without reset."))},l=()=>setTimeout(()=>u(true),0),g=setTimeout(()=>u(false),1500);a.addEventListener?.("popstate",l),r.popToTop()})}if(W.getStack().findIndex(a=>a.isFocused)!==0)throw new Error("The app isn't on its first page, so nothing was reset. Try again, or navigate without reset.");return e.replace(t),{navigated:t,replaced:true,reset:true}}var Cn=16*1024,wn=Object.freeze({__buoyOmitted:"route-params",note:"Navigation params stay on the device."});function Ct(e){return e==null?false:Sn(e,Cn)}function Oe(e){return Ct(e)?wn:e}function In(e){return Ct(e.params)?{...e,params:Oe(e.params)}:e}function Rn(e){return Ct(e.params)?{...e,params:Oe(e.params)}:e}function ho(){let e=ht();return{routes:ge.parseRouteTree(We()),source:e.source,lastUpdatedAt:e.lastLoadedAt}}var kn={version:3,getSnapshot:()=>({events:he.getEvents().map(In),sitemap:ho(),stack:W.getStack().map(Rn)}),subscribe:e=>{let t=he.subscribeToEvents(e),o=W.subscribe(e),r=null;if(!We()){let a=0,i=100,n=()=>{if(a+=1,We()){r=null,e();return}r=a<i?setTimeout(n,100):null};r=setTimeout(n,100)}return()=>{t(),o(),r&&clearTimeout(r)}},actions:{clearEvents:()=>{he.clearEvents()},getCurrentRoute:()=>{let e=he.getEvents()[0];if(e&&he.isCapturing())return{path:e.pathname,params:Oe(e.params),at:e.timestamp,source:"event"};let t=W.getStack(),o=t.find(r=>r.isFocused)??t[t.length-1];return o?.pathname?{path:o.pathname,params:Oe(o.params??{}),at:null,source:"stack"}:e?{path:e.pathname,params:Oe(e.params),at:e.timestamp,source:"event",stale:true}:{path:null,params:{},at:null,source:null}},navigate:e=>{let t=e,o=t?.path;if(!o)throw new Error("navigate requires a 'path' param");let r=vn();if(!r){let i=W.getActions(),n=o.replace(/^\//,"");if(!i?.navigateToRoute||!n)throw new Error("expo-router is not available here and no navigation container was captured \u2014 is <RouteTracker /> mounted inside your NavigationContainer?");if(!i.navigateToRoute(n,t?.params))throw new Error(`Could not navigate to "${n}" \u2014 no navigation container is live.`);return{navigated:o,replaced:false,via:"react-navigation"}}let a=[];try{a=ho().routes}catch{a=[]}if(ba()&&xn(o,a)===false)throw new Error(`No screen matches "${o}". Navigating there would open expo-router's "Unmatched Route" page, which replaces the app's layout (and disconnects Buoy). Read the sitemap for the paths this app has.`);if(t?.reset===true){if(typeof r.canDismiss!="function")return Tn(r,o);try{r.canDismiss()&&r.dismissAll?.()}catch{}return r.navigate(o),{navigated:o,replaced:false,reset:true}}return(t?.replace===true&&typeof r.replace=="function"?r.replace:r.navigate)(o),{navigated:o,replaced:t?.replace===true}},stackNavigateToIndex:e=>{let t=e?.index;if(typeof t!="number")throw new Error("stackNavigateToIndex requires a numeric 'index'");let o=W.getActions();if(!o)throw new Error("navigation stack is not available");return o.navigateToIndex(t),{navigatedToIndex:t}},stackPopToIndex:e=>{let t=e?.index;if(typeof t!="number")throw new Error("stackPopToIndex requires a numeric 'index'");let o=W.getActions();if(!o)throw new Error("navigation stack is not available");return o.popToIndex(t),{poppedToIndex:t}},stackGoBack:()=>{let e=W.getActions();if(!e)throw new Error("navigation stack is not available");return e.goBack(),{wentBack:true}},stackPopToTop:()=>{let e=W.getActions();if(!e)throw new Error("navigation stack is not available");return e.popToTop(),{poppedToTop:true}}}};export{Yt as NavigationStack,Vt as RouteEventDetail,ct as RouteEventExpandedContent,oo as RouteEventItemCompact,vt as RouteEventsModalWithTabs,Nt as RouteObserver,ge as RouteParser,mn as RouteTracker,ft as RoutesSitemap,rn as RoutesToolView,ln as createRouteEventsTool,W as navigationStackStore,fa as registerBrowserRoutes,he as routeEventStore,kn as routeEventsSyncAdapter,no as routeEventsToolPreset,Fe as routeObserver,Xt as useNavigationStack,xa as useParentRoutes,va as useRoute,At as useRouteEvents,yn as useRouteObserver,bn as useRouteObserverReactNavigation,Qe as useRouteSitemap};
|
|
6
|
+
${Ke}`)):M.alert($e,`${x.path} needs a value for ${Ue}, and this platform can't ask for one here.`);return}M.prompt($e,Ke,[{text:"Cancel",style:"cancel"},{text:R<Le.length-1?"Next":"Navigate",onPress:W=>{if(W&&W.trim()){let be={...Y,[Te]:W.trim()};ce(x,R+1,be)}else M.alert("Invalid Value","Please enter a value for the parameter")}}],"plain-text")},[E]),xe=je((x,R)=>{if(a){a(x);return}if(!$&&!R?.bypassPro){G(true);return}if(x.type==="layout"||x.type==="group"){M.alert("Cannot Navigate",`${x.type==="layout"?"Layouts":"Route groups"} are not navigable routes`);return}if(x.type==="dynamic"||x.type==="catch-all"){if(x.params.length===0){try{E.push(x.path)}catch(Y){M.alert("Navigation Error",String(Y))}return}ce(x);return}try{E.push(x.path)}catch(Y){M.alert("Navigation Error",String(Y))}},[E,ce,$,a]),ue=je(()=>{xe(ja,{bypassPro:true})},[xe]),v=je(()=>{p||(w(true),B(),setTimeout(()=>w(false),400))},[p,B]),z=Qe(()=>_?`Updated ${Ta(_)}`:"Awaiting route data",[_]),H=Qe(()=>q?`Source: ${q}`:"Source: unknown",[q]),de=Qe(()=>n&&Q.length>0?[{title:"Search Results",icon:"",routes:Q}]:C,[n,Q,C]);return re?A(u,{style:[c.container,e],children:[d&&A(u,{style:c.searchContainer,testID:"buoy-routes-sitemap-search-field",children:[h(qt,{size:16,color:b.color.textTertiary}),h(Ot,{style:c.searchInput,placeholder:"Search routes...",placeholderTextColor:b.color.placeholder,value:n,onChangeText:i,autoCapitalize:"none",autoCorrect:false,autoFocus:true,testID:"buoy-routes-sitemap-search",accessibilityLabel:"Search routes"}),n.length>0&&h(j,{onPress:()=>i(""),style:c.clearButton,testID:"buoy-routes-sitemap-search-clear",accessibilityRole:"button",accessibilityLabel:"Clear route search",children:h(m,{style:c.clearButtonText,children:"\u2715"})}),h(j,{style:c.closeSearchButton,onPress:()=>{l(false),i("")},testID:"buoy-routes-sitemap-search-done",accessibilityRole:"button",accessibilityLabel:"Done searching routes",children:h(m,{style:c.closeSearchText,children:"Done"})})]}),A(_e,{testID:"buoy-routes-sitemap-scroll",style:c.scrollView,contentContainerStyle:c.scrollContent,children:[!d&&A(u,{style:c.header,children:[A(u,{style:c.actionsRow,children:[A(u,{style:[c.actionWrapper,ee&&c.actionWrapperDesktop],children:[h(j,{style:[c.iconButton,ee&&c.iconButtonDesktop],onPress:ue,accessibilityLabel:"Go to home route",accessibilityRole:"button",testID:"buoy-routes-sitemap-home",children:h(va,{size:Ye,color:b.color.textSecondary})}),h(m,{style:[c.actionLabel,ee&&c.actionLabelDesktop],children:"Home"})]}),A(u,{style:[c.actionWrapper,ee&&c.actionWrapperDesktop],children:[h(Sa,{value:N,testID:"buoy-routes-sitemap-copy",size:ee?Ye:14,buttonStyle:ee?c.actionButtonHeaderDesktop:c.actionButtonHeader}),h(m,{style:[c.actionLabel,ee&&c.actionLabelDesktop],children:"Copy"})]}),A(u,{style:[c.actionWrapper,ee&&c.actionWrapperDesktop],children:[h(j,{style:[c.iconButton,ee&&c.iconButtonDesktop,p&&c.refreshButtonDisabled],onPress:v,disabled:p,testID:"buoy-routes-sitemap-refresh",accessibilityRole:"button",accessibilityLabel:"Refresh route tree",children:h(wa,{size:Ye,color:p?b.color.textTertiary:b.color.textSecondary})}),h(m,{style:[c.actionLabel,ee&&c.actionLabelDesktop],children:"Refresh"})]}),A(u,{style:[c.actionWrapper,ee&&c.actionWrapperDesktop],children:[h(j,{style:[c.iconButton,ee&&c.iconButtonDesktop],onPress:()=>l(true),testID:"buoy-routes-sitemap-search-open",accessibilityRole:"button",accessibilityLabel:"Search routes",children:h(qt,{size:Ye,color:b.color.textSecondary})}),h(m,{style:[c.actionLabel,ee&&c.actionLabelDesktop],children:"Search"})]})]}),A(u,{style:c.statsGrid,children:[h(Pe,{value:I.total,label:"Total",id:"total"}),h(Pe,{value:I.static,label:"Static",id:"static"}),h(Pe,{value:I.dynamic,label:"Dynamic",id:"dynamic"}),h(Pe,{value:I.catchAll,label:"Catch-All",id:"catch-all"}),h(Pe,{value:I.layouts,label:"Layouts",id:"layouts"}),h(Pe,{value:I.groups,label:"Groups",id:"groups"})]})]}),de.length===0?h(fa,{testID:"buoy-routes-sitemap-empty",otto:"map",title:"No routes found",message:"Nothing in the router matches. Clear the search to see the whole tree."}):de.map(x=>h(Va,{group:x,isExpanded:n.length>0||g.has(x.title),onToggleExpand:()=>we(x.title),onNavigate:xe},x.title)),A(u,{style:c.metaFooter,children:[h(m,{style:c.metaText,testID:"buoy-routes-sitemap-updated",children:z}),h(u,{style:c.sourceBadge,children:h(m,{style:c.sourceText,testID:"buoy-routes-sitemap-source",children:H})})]})]}),h(Ca,{visible:L,onClose:()=>G(false),featureName:"Route Navigation"})]}):h(u,{style:[c.container,e],children:h(u,{style:c.loadingContainer,children:h(m,{style:c.loadingText,testID:"buoy-routes-sitemap-loading",children:D?"Loading routes...":"Route sitemap isn't available on the dashboard \u2014 the route tree lives on the device. Use the Events tab to see navigation here."})})})}function Pe({value:e,label:t,id:o}){return A(u,{style:c.statItem,testID:`buoy-routes-stat-${o}`,accessibilityLabel:`${t}, ${e}`,children:[h(m,{style:c.statValue,testID:`buoy-routes-stat-${o}-value`,children:e}),h(m,{style:c.statLabel,children:t})]})}function Va({group:e,isExpanded:t,onToggleExpand:o,onNavigate:r}){return A(u,{style:c.groupContainer,children:[A(j,{style:c.groupHeader,onPress:o,activeOpacity:.7,testID:oo(e.title),accessibilityRole:"button",accessibilityLabel:`${e.title}, ${e.routes.length} routes`,children:[A(u,{style:c.groupHeaderLeft,children:[t?h(Yt,{size:14,color:b.color.textSecondary}):h(Xt,{size:14,color:b.color.textSecondary}),h(m,{style:c.groupTitle,children:e.title})]}),h(u,{style:c.groupBadge,children:h(m,{style:c.groupCount,testID:`${oo(e.title)}-count`,children:e.routes.length})})]}),e.description&&h(u,{style:c.groupDescription,children:h(m,{style:c.groupDescriptionText,children:e.description})}),t&&h(u,{style:c.routesList,children:e.routes.map((a,n)=>h(ro,{route:a,onNavigate:r},`${a.path}-${n}`))})]})}function ro({route:e,depth:t=0,onNavigate:o}){let[r,a]=Ee(false),n=e.children.length>0,i=Oa(e.type),d=e.type!=="layout"&&e.type!=="group",l=Na(e.path),g=n,s=g?r:true;return h(u,{style:[c.routeItem,{marginLeft:t*12}],testID:l,children:A(u,{style:c.routeCard,children:[A(u,{style:c.routeHeader,children:[g?A(j,{style:c.routeHeaderLeft,onPress:()=>a(!r),activeOpacity:.7,testID:`${l}-toggle`,accessibilityRole:"button",accessibilityLabel:`${e.path}, ${e.type}, ${e.children.length} nested`,children:[h(u,{style:c.expandIndicator,children:r?h(Yt,{size:14,color:b.color.textSecondary}):h(Xt,{size:14,color:b.color.textSecondary})}),h(m,{style:c.routePath,numberOfLines:3,testID:`${l}-path`,children:e.path})]}):A(u,{style:c.routeHeaderLeft,accessible:true,accessibilityLabel:`${e.path}, ${e.type}`,children:[h(u,{style:c.expandIndicator}),h(m,{style:c.routePath,numberOfLines:3,testID:`${l}-path`,children:e.path})]}),A(u,{style:c.routeHeaderActions,children:[n&&h(u,{style:c.childCountBadge,children:h(m,{style:c.childCountText,testID:`${l}-children-count`,children:e.children.length})}),h(u,{style:[c.typeTag,{backgroundColor:`${i}15`,borderColor:`${i}40`}],children:h(m,{style:[c.typeText,{color:i}],testID:`${l}-type`,children:e.type.toUpperCase()})}),h(xa,{value:e.path,buttonStyle:c.iconAction,testID:`${l}-copy`}),d&&h(j,{style:c.goButton,onPress:()=>o(e),activeOpacity:.7,testID:`${l}-go`,accessibilityRole:"button",accessibilityLabel:`Go to ${e.path}`,children:h(m,{style:c.goButtonText,children:"Go"})})]})]}),s&&n&&h(u,{style:c.childrenContainer,children:e.children.map((p,w)=>h(ro,{route:p,depth:t+1,onNavigate:o},`${p.path}-${w}`))})]})})}function Oa(e){switch(e){case"static":return"#3B82F6";case"dynamic":return"#F59E0B";case"catch-all":return"#EC4899";case"index":return"#10B981";case"layout":return"#8B5CF6";case"group":return"#6366F1";case"not-found":return"#EF4444";default:return"#6B7280"}}var c=ve.create({container:{flex:1,backgroundColor:"transparent"},loadingContainer:{flex:1,justifyContent:"center",alignItems:"center"},loadingText:{color:b.color.textSecondary,fontSize:14,fontFamily:Z,textAlign:"center",lineHeight:20,paddingHorizontal:32,maxWidth:420},header:{flexDirection:"column",padding:8,borderBottomWidth:1,borderBottomColor:b.color.border,gap:12,marginBottom:8},actionsRow:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",gap:12,paddingBottom:4},statsGrid:{flexDirection:"row",flexWrap:"wrap",gap:8},statItem:{flexGrow:1,flexShrink:1,flexBasis:"30%",minWidth:90,backgroundColor:b.color.surface,borderRadius:8,paddingVertical:10,paddingHorizontal:12,alignItems:"center"},statValue:{fontSize:18,fontWeight:"800",color:b.color.text,fontFamily:Z},statLabel:{fontSize:10,color:b.color.textTertiary,marginTop:4,fontFamily:Z,textTransform:"uppercase",letterSpacing:.5},actionWrapper:{flex:1,alignItems:"center",justifyContent:"center",gap:4,minWidth:48},actionWrapperDesktop:{gap:8,minWidth:72},actionButtonHeader:{padding:6,borderRadius:4,backgroundColor:b.color.surfaceElevated},actionButtonHeaderDesktop:{padding:12,borderRadius:8,backgroundColor:b.color.surfaceElevated},iconButton:{padding:6,borderRadius:4,alignItems:"center",justifyContent:"center"},iconButtonDesktop:{padding:12,borderRadius:8,backgroundColor:b.color.surfaceElevated},actionLabel:{fontSize:8,color:b.color.textTertiary,fontFamily:Z,textTransform:"uppercase",letterSpacing:.5},actionLabelDesktop:{fontSize:12},refreshButtonDisabled:{opacity:.5},metaFooter:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",gap:8,paddingHorizontal:16,paddingVertical:16,marginTop:16,borderTopWidth:1,borderTopColor:b.color.border},metaText:{fontSize:12,color:b.color.textSecondary,fontFamily:Z},sourceBadge:{paddingHorizontal:8,paddingVertical:2,borderRadius:999,borderWidth:1,borderColor:b.color.border,backgroundColor:b.color.surface},sourceText:{fontSize:11,color:b.color.textSecondary,textTransform:"capitalize",fontFamily:Z},searchContainer:{flexDirection:"row",alignItems:"center",padding:8,gap:8,borderBottomWidth:1,borderBottomColor:b.color.border},searchInput:{flex:1,color:b.color.text,fontSize:14,fontFamily:Z},clearButton:{padding:4},clearButtonText:{color:b.color.textTertiary,fontSize:18},closeSearchButton:{paddingHorizontal:8,paddingVertical:4},closeSearchText:{color:b.color.accent,fontSize:14,fontWeight:"600",fontFamily:Z},scrollView:{flex:1},scrollContent:{paddingBottom:8},emptyState:{padding:32,alignItems:"center"},emptyText:{color:b.color.textSecondary,fontSize:14,fontFamily:Z},groupContainer:{marginVertical:4},groupHeader:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",padding:12,paddingHorizontal:16,backgroundColor:b.color.surface,borderLeftWidth:3,borderLeftColor:b.color.fillTertiary},groupHeaderLeft:{flexDirection:"row",alignItems:"center",gap:8,flex:1},groupTitle:{fontSize:12,fontWeight:"700",color:b.color.text,fontFamily:Z,textTransform:"uppercase",letterSpacing:.8},groupBadge:{backgroundColor:"#3B82F615",borderColor:"#3B82F640",borderWidth:1,borderRadius:12,paddingHorizontal:8,paddingVertical:3,minWidth:24,alignItems:"center",justifyContent:"center"},groupCount:{fontSize:11,fontWeight:"600",color:"#3B82F6",fontFamily:Z},routesList:{backgroundColor:"transparent"},groupDescription:{paddingHorizontal:16,paddingVertical:8,marginBottom:8,backgroundColor:b.color.surfaceElevated,borderLeftWidth:3,borderLeftColor:b.color.fillTertiary},groupDescriptionText:{fontSize:11,color:b.color.textSecondary,fontFamily:Z,lineHeight:16},routeItem:{marginBottom:6},routeCard:{backgroundColor:b.color.surface,borderRadius:6,borderWidth:1,borderColor:b.color.border,overflow:"hidden",shadowColor:"#000",shadowOffset:{width:0,height:1},shadowOpacity:.05,shadowRadius:2,elevation:1},routeHeader:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",paddingVertical:7,paddingHorizontal:10,gap:8},expandIndicator:{width:18,alignItems:"center"},routeHeaderLeft:{flexDirection:"row",alignItems:"center",gap:8,flex:1},routePath:{fontSize:13,fontWeight:"600",color:b.color.text,fontFamily:Z,flex:1},routeHeaderActions:{flexDirection:"row",alignItems:"center",gap:6},childCountBadge:{backgroundColor:"#6B728015",borderColor:"#6B728040",borderWidth:1,borderRadius:12,paddingHorizontal:7,paddingVertical:2,minWidth:22,alignItems:"center",justifyContent:"center"},childCountText:{fontSize:11,fontWeight:"600",color:b.color.textSecondary,fontFamily:Z},typeTag:{borderRadius:4,paddingHorizontal:6,paddingVertical:2,borderWidth:1},typeText:{fontSize:10,fontWeight:"600",fontFamily:Z},iconAction:{width:28,height:24,borderRadius:4,backgroundColor:b.color.surfaceElevated,borderWidth:1,borderColor:b.color.border,alignItems:"center",justifyContent:"center"},goButton:{height:24,paddingHorizontal:10,borderRadius:4,alignItems:"center",justifyContent:"center",backgroundColor:b.color.accentSoft,borderWidth:1,borderColor:b.color.accentBorder},goButtonText:{fontSize:12,color:b.color.accent,fontFamily:Z,fontWeight:"600"},childrenContainer:{borderLeftWidth:2,borderLeftColor:b.color.border,marginLeft:16,marginRight:8,marginTop:2,marginBottom:8}});import{useState as ao,useMemo as Xe,useEffect as no}from"react";import{ChevronDown as Ha,ChevronRight as Ma,InlineCopyButton as Ua,ProUpgradeModal as Ka,buoyColors as et,night as K,useSafeAreaInsets as Ga,ToolEmptyState as _a,monoFont as le}from"@buoy-gg/shared-ui/web";import{useIsPro as Ja}from"@buoy-gg/license/web";import{DataViewer as Za}from"@buoy-gg/shared-ui/web/dataViewer";import{useSyncExternalStore as Qa}from"react";var qa=class{constructor(){this.stack=[];this.actions=null;this.listeners=new Set}getStack(){return this.stack}setStack(e){this.stack=e,this.listeners.forEach(t=>t())}getActions(){return this.actions}setActions(e){this.actions=e}subscribe(e){return this.listeners.add(e),()=>{this.listeners.delete(e)}}},V=new qa;var Ya=[];function io(){let e=Qa(r=>V.subscribe(r),()=>V.getStack(),()=>Ya),t=e.find(r=>r.isFocused)??null,o=()=>{let r=V.getActions();if(!r)throw new Error("Mount RouteTracker to capture browser navigation.");return r};return{stack:e,focusedRoute:t,stackDepth:e.length,isAtRoot:!t||t.index===0,isLoaded:e.length>0,error:null,refresh:()=>{},navigateToIndex:r=>o().navigateToIndex(r),navigateToRoute:(r,a)=>o().navigateToRoute?.(r,a)??false,popToIndex:r=>o().popToIndex(r),goBack:()=>o().goBack(),popToTop:()=>o().popToTop()}}import{jsx as k,jsxs as oe}from"react/jsx-runtime";function so({style:e,injectedStack:t,onAction:o,onCopyValueChange:r}){let a=io(),n=t!=null,i=Ga({minBottom:8}),d=n?t:a.stack,l=n?true:a.isLoaded,g=n?null:a.error,s=Xe(()=>d.find(v=>v.isFocused)??null,[d]),p=d.length,w=p<=1,L=v=>o?o("navigateToIndex",{index:v}):a.navigateToIndex(v),G=v=>o?o("popToIndex",{index:v}):a.popToIndex(v),$=()=>o?o("goBack"):a.goBack(),E=()=>o?o("popToTop"):a.popToTop(),[C,I]=ao(null),[re,D]=ao(false),Q=Ja();no(()=>{re&&Q&&D(false)},[re,Q]);let he=Xe(()=>{let v=d.map(z=>({pathname:z.pathname,name:z.name,params:z.params,isFocused:z.isFocused}));return JSON.stringify(v,null,2)},[d]);no(()=>{r?.(he)},[he,r]);let B=Xe(()=>C!==null&&d[C]?d[C]:s,[C,d,s]),_=Xe(()=>C!==null&&d[C]&&!d[C].isFocused,[C,d]);if(!l)return k(u,{style:[f.container,e],children:k(u,{style:f.loadingContainer,children:k(m,{style:f.loadingText,testID:"buoy-routes-stack-loading",children:"Loading navigation stack..."})})});if(g)return k(u,{style:[f.container,e],children:oe(u,{style:f.errorContainer,testID:"buoy-routes-stack-error",children:[k(m,{style:f.errorText,children:"Error loading stack"}),k(m,{style:f.errorDetail,testID:"buoy-routes-stack-error-detail",children:g.message})]})});if(d.length===0)return k(u,{style:[f.container,e],children:k(_a,{testID:"buoy-routes-stack-empty",otto:"walking",title:"No navigation stack",message:"Navigate to a route to see the stack"})});let q=(v,z,H,de)=>{if(o){let x=globalThis.window?.confirm;(!x||x(`${v}
|
|
7
|
+
|
|
8
|
+
${z}`))&&de();return}M.alert(v,z,[{text:"Cancel",style:"cancel"},{text:H,style:"destructive",onPress:de}])},N=()=>{if(!Q){D(true);return}if(w){M.alert("Cannot Go Back","Already at the root of the stack");return}$()},we=()=>{if(!Q){D(true);return}if(w){M.alert("Already at Top","Stack only has one screen");return}q("Pop to Top","This will remove all screens except the root screen.","Pop to Top",E)},ce=v=>{I(C===v?null:v)},xe=()=>{if(!Q){D(true);return}if(B){if(B.isFocused){M.alert("Already There","This route is already visible");return}L(B.index)}},ue=()=>{if(!Q){D(true);return}if(!B)return;if(B.isFocused){M.alert("Cannot Pop","Selected route is already visible");return}if(B.index===p-1){M.alert("Cannot Pop","No screens above selected route");return}let v=p-1-B.index,z=B.index;q("Pop to Route",`Remove ${v} screen${v!==1?"s":""} above ${B.pathname}?`,"Pop",()=>G(z))};return oe(u,{style:[f.container,e],children:[k(_e,{testID:"buoy-routes-stack-scroll",style:f.stackScroll,contentContainerStyle:[f.stackContent,{paddingBottom:f.stackContent.padding+i.bottom}],children:[...d].reverse().map((v,z)=>{let H=d.length-1-z,de=C===H,x=Object.keys(v.params).length>0,R=Wa(H);return k(u,{style:f.stackItemWrapper,testID:R,children:oe(u,{style:[f.stackItem,de&&f.stackItemSelected],children:[oe(u,{style:f.stackItemHeader,children:[oe(j,{style:f.stackItemToggle,onPress:()=>ce(H),activeOpacity:.7,testID:`${R}-toggle`,accessibilityRole:"button",accessibilityLabel:`${v.pathname}, ${v.isFocused?"focused":"mounted"}, position ${H} of ${p-1}`,children:[k(u,{style:f.expandIndicator,children:de?k(Ha,{size:14,color:K.color.textSecondary}):k(Ma,{size:14,color:K.color.textSecondary})}),k(m,{style:f.stackItemPath,numberOfLines:1,testID:`${R}-path`,children:v.pathname})]}),k(Ua,{value:v.pathname,buttonStyle:f.copyRouteButton,testID:`${R}-copy`}),k(j,{onPress:()=>ce(H),activeOpacity:.7,accessible:false,style:[f.statusBadge,{backgroundColor:v.isFocused?`${et.success}15`:"#3B82F615",borderColor:v.isFocused?`${et.success}40`:"#3B82F640"}],children:k(m,{style:[f.statusBadgeText,{color:v.isFocused?et.success:"#3B82F6"}],testID:`${R}-status`,children:v.isFocused?"FOCUSED":"MOUNTED"})})]}),de&&oe(u,{style:f.expandedContent,children:[oe(u,{style:f.detailRow,children:[k(m,{style:f.detailLabel,children:"Route Name:"}),k(m,{style:f.detailValue,testID:`${R}-name`,children:v.name})]}),oe(u,{style:f.detailRow,children:[k(m,{style:f.detailLabel,children:"Position:"}),oe(m,{style:f.detailValue,testID:`${R}-position`,children:[H," / ",p-1]})]}),x&&k(u,{style:f.dataViewerContainer,children:k(Za,{title:"Parameters",data:v.params,showTypeFilter:false})}),oe(u,{style:f.actionsRow,children:[oe(u,{style:f.actionWrapper,children:[k(j,{style:[f.actionButton,w&&f.actionButtonDisabled],onPress:N,disabled:w,testID:`${R}-back`,accessibilityRole:"button",accessibilityLabel:"Go back one screen",children:k(m,{style:[f.actionButtonText,w&&f.actionButtonTextDisabled],children:"Back"})}),k(m,{style:f.helpText,children:"Go back one screen"})]}),oe(u,{style:f.actionWrapper,children:[k(j,{style:[f.actionButton,v.isFocused&&f.actionButtonDisabled],onPress:xe,disabled:v.isFocused,testID:`${R}-go`,accessibilityRole:"button",accessibilityLabel:`Navigate to ${v.pathname}`,children:k(m,{style:[f.actionButtonText,v.isFocused&&f.actionButtonTextDisabled],children:"Go"})}),k(m,{style:f.helpText,children:"Navigate to this route"})]}),oe(u,{style:f.actionWrapper,children:[k(j,{style:[f.actionButton,(v.isFocused||H===p-1)&&f.actionButtonDisabled],onPress:ue,disabled:v.isFocused||H===p-1,testID:`${R}-pop-to`,accessibilityRole:"button",accessibilityLabel:`Remove screens above ${v.pathname}`,children:k(m,{style:[f.actionButtonText,(v.isFocused||H===p-1)&&f.actionButtonTextDisabled],children:"Pop To"})}),k(m,{style:f.helpText,children:"Remove screens above this"})]})]})]})]})},`stack-${H}-${v.key}`)})}),k(Ka,{visible:re,onClose:()=>D(false),featureName:"Stack Navigation"})]})}var f=ve.create({container:{flex:1,backgroundColor:"transparent"},loadingContainer:{flex:1,justifyContent:"center",alignItems:"center",padding:32},loadingText:{color:K.color.textSecondary,fontSize:14,fontFamily:le},errorContainer:{flex:1,justifyContent:"center",alignItems:"center",padding:32},errorText:{color:et.error,fontSize:16,fontWeight:"600",fontFamily:le,marginBottom:8},errorDetail:{color:K.color.textSecondary,fontSize:12,fontFamily:le,textAlign:"center"},emptyContainer:{flex:1,justifyContent:"center",alignItems:"center",padding:32},emptyText:{color:K.color.text,fontSize:16,fontWeight:"600",fontFamily:le,marginBottom:8},emptySubtext:{color:K.color.textSecondary,fontSize:14,fontFamily:le,textAlign:"center"},stackScroll:{flex:1},stackContent:{padding:8},stackItemWrapper:{marginBottom:6},stackItem:{backgroundColor:K.color.surface,borderRadius:6,borderWidth:1,borderColor:K.color.border,overflow:"hidden"},stackItemSelected:{borderColor:K.color.accent,borderWidth:2},stackItemHeader:{flexDirection:"row",alignItems:"center",paddingVertical:10,paddingHorizontal:12,gap:8},stackItemToggle:{flex:1,flexDirection:"row",alignItems:"center",gap:8},expandIndicator:{width:20,alignItems:"center"},stackItemPath:{fontSize:13,fontWeight:"600",color:K.color.text,fontFamily:le,flex:1},copyRouteButton:{padding:4,marginLeft:4},statusBadge:{borderRadius:4,paddingHorizontal:6,paddingVertical:2,borderWidth:1},statusBadgeText:{fontSize:10,fontWeight:"600",fontFamily:le},expandedContent:{paddingHorizontal:12,paddingTop:8,paddingBottom:12,borderTopWidth:1,borderTopColor:K.color.border},detailRow:{marginBottom:8},detailLabel:{fontSize:10,color:K.color.textSecondary,fontFamily:le,marginBottom:2},detailValue:{fontSize:12,color:K.color.text,fontFamily:le},dataViewerContainer:{marginTop:4,marginHorizontal:-12,marginBottom:8},actionsRow:{flexDirection:"row",gap:6,marginTop:12},actionWrapper:{flex:1},actionButton:{backgroundColor:K.color.surfaceElevated,paddingVertical:8,paddingHorizontal:8,borderRadius:6,alignItems:"center"},actionButtonDisabled:{opacity:.5},actionButtonText:{fontSize:12,fontWeight:"600",color:K.color.text,fontFamily:le},actionButtonTextDisabled:{color:K.color.textTertiary},helpText:{fontSize:9,color:K.color.textSecondary,fontFamily:le,textAlign:"center",marginTop:4,lineHeight:12}});import{useCallback as Xa}from"react";import{Navigation as en,night as wt,EVENT_LIST_PRESET as tn,monoFont as lo}from"@buoy-gg/shared-ui/web";import{memo as on,useMemo as me}from"react";import{CompactRow as rn,RelativeTime as an,buoyColors as co,night as tt,monoFont as uo}from"@buoy-gg/shared-ui/web";import{jsx as Oe}from"react/jsx-runtime";function nn(e){return e.pathname==="/"?"home":ht(e.pathname,e.segments)?"dynamic":e.params&&Object.keys(e.params).length>0?"with-params":"default"}function sn(e){switch(e){case"home":return co.success;case"dynamic":return tt.color.accent;case"with-params":return co.warning;default:return tt.color.textSecondary}}function ln(e){switch(e){case"home":return"Home";case"dynamic":return"Dynamic";case"with-params":return"Params";default:return"Static"}}function cn(e){if(e<1e3)return`${Math.round(e)}ms`;if(e<6e4)return`${(e/1e3).toFixed(1)}s`;let t=Math.floor(e/6e4),o=Math.floor(e%6e4/1e3);return o>0?`${t}m ${o}s`:`${t}m`}function un(e){let t=[];e.timeSincePrevious!==void 0&&e.timeSincePrevious>0&&t.push(cn(e.timeSincePrevious));let o=e.segments?.length||0;return o>0&&t.push(`depth ${o}`),t.join(" \xB7 ")||"root"}function dn(e){if(e.params&&Object.keys(e.params).length>0){let t=Object.keys(e.params).length;return`${t} PARAM${t!==1?"S":""}`}}var po=on(function({event:e,visitNumber:t,isExpanded:o,onPress:r,onNavigate:a,index:n}){let i=me(()=>nn(e),[e]),d=me(()=>ht(e.pathname,e.segments),[e.pathname,e.segments]),l=me(()=>sn(i),[i]),g=me(()=>ln(i),[i]),s=me(()=>un(e),[e]),p=me(()=>dn(e),[e]),w=me(()=>Aa(e.pathname,t),[e.pathname,t]),L=me(()=>`${e.pathname}, ${g}, ${s}`,[e.pathname,g,s]),G=me(()=>{if(o)return Oe(mt,{event:e,visitNumber:t,routeTemplate:d})},[o,e,t,d]),$=me(()=>{if(a)return Oe(j,{style:mo.goButton,onPress:()=>a(_t(e.pathname,e.params)),testID:`${w}-go`,accessibilityRole:"button",accessibilityLabel:`Go to ${e.pathname}`,children:Oe(m,{style:mo.goButtonText,children:"Go"})})},[a,e.pathname,w]);return Oe(rn,{statusDotColor:l,statusLabel:g,statusSublabel:s,primaryText:e.pathname,badgeText:p,badgeColor:l,trailingAction:$,bottomRightText:Oe(an,{timestamp:e.timestamp}),showChevron:true,expandedContent:G,isExpanded:o,expandedGlowColor:l,onPress:()=>r(n),testID:w,statusTestID:`${w}-status`,statusSublabelTestID:`${w}-sublabel`,accessibilityLabel:L})}),mo=ve.create({badgeText:{fontSize:11,fontWeight:"600",fontFamily:uo},goButton:{backgroundColor:tt.color.accent,paddingHorizontal:8,paddingVertical:4,borderRadius:4},goButtonText:{fontSize:10,fontWeight:"600",color:tt.color.onAccent,fontFamily:uo}});import{jsx as He,jsxs as pn}from"react/jsx-runtime";function mn({events:e,visitCounts:t,onNavigate:o,onSelectEvent:r}){let a=Xa(n=>{let i=e[n];i&&r(i,t.get(i)||1)},[e,t,r]);return e.length===0?pn(u,{style:ot.emptyState,testID:"buoy-routes-empty",children:[He(en,{size:48,color:wt.color.textTertiary}),He(m,{style:ot.emptyTitle,testID:"buoy-routes-empty-title",children:"No events yet"}),He(m,{style:ot.emptySubtitle,testID:"buoy-routes-empty-subtitle",children:"Navigation events will appear here"})]}):He(Nt,{testID:"buoy-routes-timeline",contentContainerStyle:ot.listContent,data:e,keyExtractor:n=>`${n.timestamp}-${n.pathname}`,renderItem:({item:n,index:i})=>He(po,{event:n,visitNumber:t.get(n)||1,isExpanded:false,index:i,onPress:a,onNavigate:o}),showsVerticalScrollIndicator:true,...tn})}var ot=ve.create({listContent:{paddingVertical:8},emptyState:{flex:1,justifyContent:"center",alignItems:"center",padding:32},emptyTitle:{color:wt.color.text,fontSize:16,fontWeight:"600",marginTop:16,marginBottom:8,fontFamily:lo,letterSpacing:.5,textTransform:"uppercase"},emptySubtitle:{color:wt.color.textSecondary,fontSize:14,textAlign:"center",fontFamily:lo}});import{Fragment as hn,jsx as T,jsxs as ne}from"react/jsx-runtime";var Tt=jr(),gn={parse:e=>e==="routes"||e==="events"||e==="stack"?e:void 0,serialize:e=>e},fn={parse:e=>e==="true",serialize:e=>e.toString()},yn={parse:e=>new Set(JSON.parse(e)),serialize:e=>JSON.stringify(Array.from(e))};function ho(e,t){if(!e||!e.routes)return null;for(let o of e.routes){if(o.name===t)return[o.name];if(o.state){let r=ho(o.state,t);if(r)return[o.name,...r]}}return null}function bn(e,t){if(e.length===0)return null;let o=t&&Object.keys(t).length>0?t:void 0;if(e.length===1)return Tt.navigate(o?{name:e[0],params:o}:{name:e[0]});let r=o?{screen:e[e.length-1],params:o}:{screen:e[e.length-1]};for(let a=e.length-2;a>=1;a--)r={screen:e[a],params:r};return Tt.navigate({name:e[0],params:r})}function Ct({visible:e,onClose:t,onBack:o,onMinimize:r,enableSharedModalDimensions:a=false,inline:n=false,remote:i}){let d=Vr(),l=void 0,g=st.OS==="web"||Or(),[s,p]=ct(Fe.routeEvents.activeTab(),"events",gn),[w,L]=Ie(false),[G,$]=Ie(""),E=ta(),C=ea("routeEvents.entries");Ft(()=>{w&&E&&L(false)},[w,E]);let[I,re]=ct(Fe.routeEvents.isMonitoring(),true,fn),{events:D,clearEvents:Q,isListening:he}=Gt({enabled:I}),B=I&&he;Ft(()=>{fe.setBootCapture(I)},[I]);let[_,q]=Ie(false),[N,we]=Ie(null),[ce,xe]=Ie(1),[ue,v]=Ie(""),[z,H]=ct(Fe.routeEvents.eventFilters(),new Set(["/_sitemap","/api","/__dev"]),yn),de=zo(null),x=pe(y=>{},[]),R=pe(y=>{try{if(i){if(!i.onNavigatePath)return;if(!E&&y!=="/"){L(true);return}i.onNavigatePath(y);return}if(g)d.push(y);else if(l){let{pathname:P,params:X}=da(y),ge=P.startsWith("/")?P.slice(1):P,Ce=Object.keys(X).length>0,ke=l.getRootState?.();if(ke){let Ge=ho(ke,ge);if(Ge){let Lt=bn(Ge,X);if(Lt){l.dispatch(Lt);return}}}l.dispatch(Tt.navigate(Ce?{name:ge,params:X}:{name:ge}))}else M.alert("Navigation Unavailable","No Expo Router or React Navigation container was found in this app.")}catch(P){M.alert("Navigation Error",String(P))}},[d,l,g,i,E]),Y=pe(()=>{re(y=>!y)},[]),Le=pe(()=>{if(D.length!==0){if(!E){L(true);return}Q()}},[D.length,E,Q]),Te=pe(y=>{H(P=>{let X=new Set(P);return X.has(y)?X.delete(y):X.add(y),X})},[]),Ue=pe(y=>{H(P=>new Set([...P,y]))},[]),$e=pe(()=>{q(!_)},[_]),Ke=pe((y,P)=>{we(y),xe(P)},[]),rt=pe(()=>{we(null)},[]),W=pe(y=>{we(null),p(y)},[]),be=Re(()=>{let y=new Set;return D.forEach(P=>{P.pathname&&y.add(P.pathname)}),Array.from(y).sort()},[D]),ie=Re(()=>D.filter(y=>{if(!y.pathname||Array.from(z).some(P=>y.pathname.includes(P)))return false;if(ue.trim()){let P=ue.toLowerCase(),X=y.pathname.toLowerCase().includes(P),ge=Object.entries(y.params||{}).some(([Ce,ke])=>{let Ge=Array.isArray(ke)?ke.join(" "):ke;return Ce.toLowerCase().includes(P)||Ge.toLowerCase().includes(P)});return X||ge}return true}),[D,z,ue]),Co=Re(()=>ie.slice(0,C),[ie,C]),at=Re(()=>Math.max(0,ie.length-C),[ie.length,C]),nt=Re(()=>{let y=new Map,P=new Map;for(let X=D.length-1;X>=0;X--){let ge=D[X],Ce=(y.get(ge.pathname)||0)+1;y.set(ge.pathname,Ce),P.set(ge,Ce)}return P},[D]),ko=Re(()=>({summary:{total:D.length,filtered:ie.length,listening:B,ignoredPatterns:Array.from(z),timestamp:new Date().toISOString()},events:ie.map((y,P)=>({index:P,visitNumber:nt.get(y)||1,pathname:y.pathname,timestamp:y.timestamp,timestampRelative:_r(y.timestamp),params:y.params,segments:y.segments,previousPathname:y.previousPathname,timeSincePrevious:y.timeSincePrevious}))}),[D.length,ie,B,z,nt]);if(!e)return null;let Io=a?Fe.modal.root():Fe.routeEvents.modal(),it=null,Et=()=>{if(N)return T(Zt,{event:N,visitNumber:ce,onNavigate:R});if(s==="routes")return g||i?.sitemap?T(St,{style:O.contentWrapper,injectedRoutes:i?.sitemap?.routes,injectedSource:i?.sitemap?.source??null,injectedLastUpdatedAt:i?.sitemap?.lastUpdatedAt??null,onNavigateRoute:i?Ro:void 0}):T(St,{style:O.contentWrapper});if(s==="stack")return T(so,{style:O.contentWrapper,injectedStack:i?i.stack??[]:void 0,onAction:i?.onStackAction,onCopyValueChange:$});if(_)return T(ha,{ignoredPatterns:z,onTogglePattern:Te,onAddPattern:Ue,availablePathnames:be});let y=D.length>0;return ie.length===0?ne(u,{style:O.contentWrapper,testID:"buoy-routes-events",children:[y&&T(u,{style:O.searchContainer,testID:"buoy-routes-search-field",children:T(Mt,{value:ue,onChange:v,placeholder:"Search pathname or params...",testID:"buoy-routes-search"})}),T(Mr,{testID:"buoy-routes-empty",...Ur({subject:"route events",search:ue,total:D.length,capturing:B,waiting:{otto:"walking",title:"No route events yet",message:"Navigation events will appear here"},paused:{title:"Event listener is paused",message:"Press play to start monitoring"}})})]}):ne(u,{style:O.contentWrapper,testID:"buoy-routes-events",children:[T(u,{style:O.searchContainer,testID:"buoy-routes-search-field",children:T(Mt,{value:ue,onChange:v,placeholder:"Search pathname or params...",testID:"buoy-routes-search"})}),at>0&&ne(u,{style:O.lockedEventsBanner,testID:"buoy-routes-locked-banner",children:[T(Qr,{size:14,color:J.color.warning}),ne(m,{style:O.lockedEventsBannerText,testID:"buoy-routes-locked-banner-text",children:[at," older ",at===1?"event":"events"," locked"]}),T(m,{style:O.lockedEventsBannerSubtext,children:"Upgrade to Pro for full history"})]}),T(mn,{events:Co,visitCounts:nt,onNavigate:R,onSelectEvent:Ke})]})},Dt=N?ne(se,{children:[T(se.Navigation,{onBack:rt}),T(se.Content,{title:N.pathname,testID:"buoy-routes-detail-title"}),T(se.Actions,{children:T(ut,{testID:"buoy-routes-detail-copy",value:{pathname:N.pathname,previousPathname:N.previousPathname,params:N.params,segments:N.segments,timestamp:N.timestamp,timestampISO:new Date(N.timestamp).toISOString(),timeSincePrevious:N.timeSincePrevious,visitNumber:ce},buttonStyle:O.iconButton})})]}):_?ne(se,{children:[T(se.Navigation,{onBack:()=>q(false)}),T(se.Content,{title:"Filters",testID:"buoy-routes-filters-title"})]}):ne(se,{children:[o&&T(se.Navigation,{onBack:o}),T(se.Content,{title:"",noMargin:true,children:T(Gr,{tabs:[{key:"routes",label:g?"Routes":"Screens"},{key:"events",label:`Events${D.length>0&&s!=="events"?` (${D.length})`:""}`},{key:"stack",label:"Stack"}],activeTab:s,onTabChange:y=>W(y),testIDPrefix:"buoy-routes-tab"})}),ne(se.Actions,{children:[s==="stack"&&T(ut,{value:G,buttonStyle:O.iconButton,testID:"buoy-routes-stack-copy"}),s==="events"&&ne(hn,{children:[T(ut,{value:ko,buttonStyle:O.iconButton,testID:"buoy-routes-copy"}),T(j,{onPress:$e,style:[O.iconButton,z.size>0&&O.activeFilterButton],testID:"buoy-routes-filters",accessibilityRole:"button",accessibilityLabel:z.size>0?`Route filters, ${z.size} active`:"Route filters",children:T(Zr,{size:14,color:z.size>0?J.color.accent:J.color.textSecondary})}),T(Yr,{isEnabled:B,onToggle:Y,accessibilityLabel:"Toggle route event monitoring",testID:"buoy-routes-power"}),T(j,{onPress:Le,style:O.iconButton,testID:"buoy-routes-clear",accessibilityRole:"button",accessibilityLabel:"Clear route events",children:T(Jr,{size:14,color:J.color.danger})})]})]})]}),Ro=y=>{if(y.type==="layout"||y.type==="group")return;let P=y.type==="index"||y.path==="/";if(!E&&!P){L(true);return}i?.onNavigateRoute?.(y)},Pt=T(qr,{visible:w,onClose:()=>L(false),featureName:"Route Event Management"});return n?ne(Ut,{children:[ne(u,{style:O.inlineRoot,children:[T(u,{style:O.inlineHeader,...Hr,children:Dt}),Et(),it]}),Pt]}):T(Ut,{children:ne(Kr,{visible:e,onClose:t,onMinimize:r,persistenceKey:Io,header:{showToggleButton:true,customContent:Dt},onModeChange:x,enablePersistence:true,initialMode:"bottomSheet",enableGlitchEffects:true,disableScrollWrapper:true,styles:{},footer:it,footerHeight:it?68:0,children:[Et(),Pt]})})}function vn(e={}){return T(Ct,{...e,inline:true,visible:true,onClose:()=>{}})}var O=ve.create({inlineRoot:{flex:1,minHeight:0,backgroundColor:"transparent"},inlineHeader:{paddingHorizontal:12,paddingVertical:8,borderBottomWidth:1,borderBottomColor:Xr.border,backgroundColor:"transparent"},iconButton:{padding:6,borderRadius:6,backgroundColor:J.color.buttonSurface},activeFilterButton:{backgroundColor:J.color.accentSoft},emptyState:{flex:1,justifyContent:"center",alignItems:"center",padding:32},emptyTitle:{color:J.color.text,fontSize:16,fontWeight:"600",marginTop:16,marginBottom:8,fontFamily:Je,letterSpacing:.5,textTransform:"uppercase"},emptySubtitle:{color:J.color.textSecondary,fontSize:14,textAlign:"center",fontFamily:Je},contentWrapper:{flex:1},statsContainer:{paddingHorizontal:16,paddingVertical:8,backgroundColor:J.color.surface,borderBottomWidth:1,borderBottomColor:J.color.border},statsText:{fontSize:11,color:J.color.textSecondary,fontFamily:Je,textAlign:"center"},statsWarning:{color:J.color.warning,fontWeight:"600"},searchContainer:{paddingHorizontal:16,paddingVertical:8,backgroundColor:"transparent"},lockedEventsBanner:{flexDirection:"row",alignItems:"center",gap:8,backgroundColor:J.color.warningSoft,borderWidth:1,borderColor:J.color.warning+"30",borderRadius:8,paddingVertical:10,paddingHorizontal:14,marginHorizontal:16,marginBottom:8},lockedEventsBannerText:{fontSize:12,fontWeight:"600",color:J.color.warning,fontFamily:Je},lockedEventsBannerSubtext:{fontSize:11,color:J.color.textSecondary,marginLeft:"auto"}});import{createToolFactory as xn,defineToolPreset as Sn}from"@buoy-gg/shared-ui/web";import{jsx as wn}from"react/jsx-runtime";var go=Sn({id:"route-events",name:"ROUTES",description:"Route tracking & navigation inspector",slot:"both",icon:({size:e})=>wn($o,{size:e}),component:Ct,props:{enableSharedModalDimensions:false}}),Tn=xn(go,e=>({enableSharedModalDimensions:e.enableSharedModalDimensions??false}));import{useEffect as Cn}from"react";import{browserRouter as fo,getBrowserHref as kn,getBrowserRouteURL as yo,subscribeBrowserNavigation as In}from"@buoy-gg/shared-ui/web/utils";var bo=0,kt;function Rn(){if(typeof window>"u")return()=>{};if(bo++===0){fe.hydrateBootCapture();let t,o,r="",a=[],n=-1,i=()=>{let s=window.history.state;if(!s||typeof s!="object")return;let p=s.key??s.__TSR_key;return typeof p=="string"||typeof p=="number"?String(p):void 0},d=s=>{for(let p=n-1;p>=0;p--)if(a[p].href===s)return p;for(let p=n+1;p<a.length;p++)if(a[p].href===s)return p;return-1},l=s=>{let p=i();if(s.href===r&&s.kind==="pop"&&(p===void 0||a[n]?.key===p))return;if(s.kind==="replace"&&n>=0)a[n]={href:s.href,key:p};else if(s.kind==="pop"){let $=p===void 0?-1:a.findIndex(C=>C.key===p),E=$>=0?$:d(s.href);E>=0?n=E:(a.splice(n+1),a.push({href:s.href,key:p}),n++)}else a.splice(n+1),a.push({href:s.href,key:p}),n++;r=s.href;let w=yo(s.href),L=Date.now(),G=to(w.pathname);La()||Ae.emit({pathname:w.pathname,params:{...G.params,...Object.fromEntries(w.searchParams)},segments:G.segments,previousPathname:t,timestamp:L,timeSincePrevious:o===void 0?void 0:L-o}),t=w.pathname,o=L,V.setStack(a.slice(0,n+1).map(({href:$},E)=>{let C=yo($),I=to(C.pathname);return{key:`browser:${E}`,name:I.segments.join("/")||"index",pathname:C.pathname,params:{...I.params,...Object.fromEntries(C.searchParams)},index:E,isFocused:E===n,canPop:E>0}}))},g=s=>{if(!Number.isInteger(s)||s<0||s>=a.length)throw new Error("That browser history entry is unavailable.");window.history.go(s-n)};V.setActions({navigateToIndex:g,popToIndex:g,goBack:fo.back,popToTop:()=>g(0),navigateToRoute:(s,p)=>{let w={...p},L=`/${s.replace(/^\//,"")}`.replace(/\[(\.\.\.)?([^\]]+)\]/g,(G,$,E)=>{if(!(E in w))return G;let C=w[E];return delete w[E],$&&Array.isArray(C)?C.map(I=>encodeURIComponent(String(I))).join("/"):encodeURIComponent(String(C))});return fo.push({pathname:L==="/index"?"/":L,params:w}),true}}),kt=In(l),l({href:kn(),kind:"initial"})}let e=false;return()=>{e||(e=true,--bo===0&&(kt?.(),kt=void 0,V.setActions(null)))}}function Bn(){return Cn(Rn,[]),null}import{useEffect as vo,useRef as It}from"react";import{useSafePathname as En,useSafeSegments as Dn,useSafeGlobalSearchParams as Pn}from"@buoy-gg/shared-ui/web";function Ln(e){let t=En(),o=Dn(),r=Pn(),a=It(e),n=It(void 0),i=It(void 0);vo(()=>{a.current=e},[e]),vo(()=>{let d=Date.now(),l=i.current?d-i.current:void 0,g={pathname:t,params:r,segments:o,timestamp:d,previousPathname:n.current,timeSincePrevious:l};n.current=t,i.current=d,Ae.emit(g),a.current&&a.current(g)},[t,o,r])}import{useEffect as xo,useRef as Rt}from"react";function So(e){if(!e||!e.routes||e.routes.length===0)return{route:null,segments:[]};let t=e.routes[e.index??0],o=[t.name];if(t.state){let r=So(t.state);if(r.route)return{route:r.route,segments:[...o,...r.segments]}}return{route:t,segments:o}}function wo(e,t,o,r){if(!e)return;let{route:a,segments:n}=So(e);if(!a)return;let i=`/${a.name}`;if(i===t.current)return;let d=Date.now(),l=o.current?d-o.current:void 0,g={pathname:i,params:a.params||{},segments:n,timestamp:d,previousPathname:t.current,timeSincePrevious:l};t.current=i,o.current=d,Ae.emit(g),r.current&&r.current(g)}function $n(e){let t=void 0,o=Rt(e),r=Rt(void 0),a=Rt(void 0);xo(()=>{o.current=e},[e]),xo(()=>{if(!t)return;let n=t.getRootState?.();n&&wo(n,r,a,o);let i=t.addListener?.("state",()=>{let d=t.getRootState?.();wo(d,r,a,o)});return()=>{i?.()}},[t])}import{getSafeRouter as zn}from"@buoy-gg/shared-ui/web";function Fn(e,t){let o=[],r=false,a=d=>{for(let l of d??[])(l.name?.includes("+not-found")||l.path?.includes("+not-found"))&&(r=true),typeof l.path=="string"&&o.push(l.path),a(l.children)};if(a(t),r||o.length===0)return;let n=d=>"/"+d.split("?")[0].split("#")[0].split("/").filter(l=>l&&!/^\(.*\)$/.test(l)).join("/"),i=n(e);return o.some(d=>{let l=n(d);return l===i?true:new RegExp("^"+l.split("/").map(g=>/^\[\.\.\..+\]$/.test(g)?".+":/^\[.+\]$/.test(g)?"[^/]+":g.replace(/[.*+?^${}()|\\]/g,"\\$&")).join("/")+"$").test(i)})}import{isOverWireBudget as An}from"@buoy-gg/shared-ui/web";async function Nn(e,t){let o=V.getStack().findIndex(a=>a.isFocused),r=V.getActions();if(o<0||!r||typeof e.replace!="function")throw new Error("This app's history isn't captured yet, so Buoy can't start over. Open the Routes tool once, or navigate without reset.");if(o>0){let a=globalThis;await new Promise((n,i)=>{let d=s=>{clearTimeout(g),a.removeEventListener?.("popstate",l),s?n():i(new Error("The app didn't go back to its first page, so nothing was reset. Try again, or navigate without reset."))},l=()=>setTimeout(()=>d(true),0),g=setTimeout(()=>d(false),1500);a.addEventListener?.("popstate",l),r.popToTop()})}if(V.getStack().findIndex(a=>a.isFocused)!==0)throw new Error("The app isn't on its first page, so nothing was reset. Try again, or navigate without reset.");return e.replace(t),{navigated:t,replaced:true,reset:true}}var Wn=16*1024,jn=Object.freeze({__buoyOmitted:"route-params",note:"Navigation params stay on the device."});function Bt(e){return e==null?false:An(e,Wn)}function Me(e){return Bt(e)?jn:e}function Vn(e){return Bt(e.params)?{...e,params:Me(e.params)}:e}function On(e){return Bt(e.params)?{...e,params:Me(e.params)}:e}function To(){let e=vt();return{routes:ye.parseRouteTree(Ve()),source:e.source,lastUpdatedAt:e.lastLoadedAt}}var Hn={version:3,getSnapshot:()=>({events:fe.getEvents().map(Vn),sitemap:To(),stack:V.getStack().map(On)}),subscribe:e=>{let t=fe.subscribeToEvents(e),o=V.subscribe(e),r=null;if(!Ve()){let a=0,n=100,i=()=>{if(a+=1,Ve()){r=null,e();return}r=a<n?setTimeout(i,100):null};r=setTimeout(i,100)}return()=>{t(),o(),r&&clearTimeout(r)}},actions:{clearEvents:()=>{fe.clearEvents()},getCurrentRoute:()=>{let e=fe.getEvents()[0];if(e&&fe.isCapturing())return{path:e.pathname,params:Me(e.params),at:e.timestamp,source:"event"};let t=V.getStack(),o=t.find(r=>r.isFocused)??t[t.length-1];return o?.pathname?{path:o.pathname,params:Me(o.params??{}),at:null,source:"stack"}:e?{path:e.pathname,params:Me(e.params),at:e.timestamp,source:"event",stale:true}:{path:null,params:{},at:null,source:null}},navigate:e=>{let t=e,o=t?.path;if(!o)throw new Error("navigate requires a 'path' param");let r=zn();if(!r){let n=V.getActions(),i=o.replace(/^\//,"");if(!n?.navigateToRoute||!i)throw new Error("expo-router is not available here and no navigation container was captured \u2014 is <RouteTracker /> mounted inside your NavigationContainer?");if(!n.navigateToRoute(i,t?.params))throw new Error(`Could not navigate to "${i}" \u2014 no navigation container is live.`);return{navigated:o,replaced:false,via:"react-navigation"}}let a=[];try{a=To().routes}catch{a=[]}if($a()&&Fn(o,a)===false)throw new Error(`No screen matches "${o}". Navigating there would open expo-router's "Unmatched Route" page, which replaces the app's layout (and disconnects Buoy). Read the sitemap for the paths this app has.`);if(t?.reset===true){if(typeof r.canDismiss!="function")return Nn(r,o);try{r.canDismiss()&&r.dismissAll?.()}catch{}return r.navigate(o),{navigated:o,replaced:false,reset:true}}return(t?.replace===true&&typeof r.replace=="function"?r.replace:r.navigate)(o),{navigated:o,replaced:t?.replace===true}},stackNavigateToIndex:e=>{let t=e?.index;if(typeof t!="number")throw new Error("stackNavigateToIndex requires a numeric 'index'");let o=V.getActions();if(!o)throw new Error("navigation stack is not available");return o.navigateToIndex(t),{navigatedToIndex:t}},stackPopToIndex:e=>{let t=e?.index;if(typeof t!="number")throw new Error("stackPopToIndex requires a numeric 'index'");let o=V.getActions();if(!o)throw new Error("navigation stack is not available");return o.popToIndex(t),{poppedToIndex:t}},stackGoBack:()=>{let e=V.getActions();if(!e)throw new Error("navigation stack is not available");return e.goBack(),{wentBack:true}},stackPopToTop:()=>{let e=V.getActions();if(!e)throw new Error("navigation stack is not available");return e.popToTop(),{poppedToTop:true}}}};export{so as NavigationStack,Zt as RouteEventDetail,mt as RouteEventExpandedContent,po as RouteEventItemCompact,Ct as RouteEventsModalWithTabs,Kt as RouteObserver,ye as RouteParser,Bn as RouteTracker,St as RoutesSitemap,vn as RoutesToolView,Pa as claimBrowserRouteEvents,Tn as createRouteEventsTool,V as navigationStackStore,Ea as registerBrowserRoutes,fe as routeEventStore,Hn as routeEventsSyncAdapter,go as routeEventsToolPreset,Ae as routeObserver,io as useNavigationStack,Fa as useParentRoutes,za as useRoute,Gt as useRouteEvents,Ln as useRouteObserver,$n as useRouteObserverReactNavigation,qe as useRouteSitemap};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@buoy-gg/route-events",
|
|
3
|
-
"version": "7.0.
|
|
3
|
+
"version": "7.0.64",
|
|
4
4
|
"description": "Inspect reported navigation state and supported route actions in React Native apps using Expo Router or React Navigation.",
|
|
5
5
|
"main": "lib/commonjs/index.js",
|
|
6
6
|
"module": "lib/module/index.js",
|
|
@@ -34,11 +34,11 @@
|
|
|
34
34
|
],
|
|
35
35
|
"sideEffects": false,
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@buoy-gg/
|
|
38
|
-
"@buoy-gg/
|
|
37
|
+
"@buoy-gg/floating-tools-core": "^7.0.64",
|
|
38
|
+
"@buoy-gg/shared-ui": "^7.0.64"
|
|
39
39
|
},
|
|
40
40
|
"peerDependencies": {
|
|
41
|
-
"@buoy-gg/license": "7.0.
|
|
41
|
+
"@buoy-gg/license": "7.0.64",
|
|
42
42
|
"react": "*"
|
|
43
43
|
},
|
|
44
44
|
"peerDependenciesMeta": {
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
"@types/react-native": "^0.73.0",
|
|
66
66
|
"expo-router": "~5.0.7",
|
|
67
67
|
"typescript": "~5.8.3",
|
|
68
|
-
"@buoy-gg/license": "^7.0.
|
|
68
|
+
"@buoy-gg/license": "^7.0.64"
|
|
69
69
|
},
|
|
70
70
|
"react-native-builder-bob": {
|
|
71
71
|
"source": "src",
|