@buoy-gg/route-events 7.0.43 → 7.0.45
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/lib/commonjs/sync/routeEventsSyncAdapter.js +1 -1
- package/lib/commonjs/sync/sitemapMatch.js +1 -0
- package/lib/module/sync/routeEventsSyncAdapter.js +1 -1
- package/lib/module/sync/sitemapMatch.js +1 -0
- package/lib/typescript/sync/routeEventsSyncAdapter.d.ts +7 -0
- package/lib/typescript/sync/sitemapMatch.d.ts +19 -0
- package/lib/web/index.mjs +4 -4
- package/package.json +5 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.routeEventsSyncAdapter=exports.SNAPSHOT_PARAM_INLINE_LIMIT=void 0;var _sharedUi=require("@buoy-gg/shared-ui");var _routeEventStore=require("../stores/routeEventStore");var _navigationStackStore=require("../stores/navigationStackStore");var _RouteParser=require("../RouteParser");var _expoRouterStore=require("../expoRouterStore");const SNAPSHOT_PARAM_INLINE_LIMIT=exports.SNAPSHOT_PARAM_INLINE_LIMIT=16*1024;const PARAMS_ON_DEVICE=Object.freeze({__buoyOmitted:"route-params",note:"Navigation params stay on the device."});function shouldOmitParams(t){if(t==null)return false;return(0,_sharedUi.isOverWireBudget)(t,SNAPSHOT_PARAM_INLINE_LIMIT)}function toWireParams(t){if(!shouldOmitParams(t))return t;return PARAMS_ON_DEVICE}function toWireEvent(t){if(!shouldOmitParams(t.params))return t;return{...t,params:toWireParams(t.params)}}function toWireStackItem(t){if(!shouldOmitParams(t.params))return t;return{...t,params:toWireParams(t.params)}}function getSitemapSnapshot(){const t=(0,_expoRouterStore.getRouteNodeMetadata)();return{routes:_RouteParser.RouteParser.parseRouteTree((0,_expoRouterStore.loadRouteNode)()),source:t.source,lastUpdatedAt:t.lastLoadedAt}}const routeEventsSyncAdapter=exports.routeEventsSyncAdapter={version:3,getSnapshot:()=>({events:_routeEventStore.routeEventStore.getEvents().map(toWireEvent),sitemap:getSitemapSnapshot(),stack:_navigationStackStore.navigationStackStore.getStack().map(toWireStackItem)}),subscribe:t=>{const
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.routeEventsSyncAdapter=exports.SNAPSHOT_PARAM_INLINE_LIMIT=void 0;var _sharedUi=require("@buoy-gg/shared-ui");var _sitemapMatch=require("./sitemapMatch");var _routeEventStore=require("../stores/routeEventStore");var _navigationStackStore=require("../stores/navigationStackStore");var _RouteParser=require("../RouteParser");var _expoRouterStore=require("../expoRouterStore");const SNAPSHOT_PARAM_INLINE_LIMIT=exports.SNAPSHOT_PARAM_INLINE_LIMIT=16*1024;const PARAMS_ON_DEVICE=Object.freeze({__buoyOmitted:"route-params",note:"Navigation params stay on the device."});function shouldOmitParams(t){if(t==null)return false;return(0,_sharedUi.isOverWireBudget)(t,SNAPSHOT_PARAM_INLINE_LIMIT)}function toWireParams(t){if(!shouldOmitParams(t))return t;return PARAMS_ON_DEVICE}function toWireEvent(t){if(!shouldOmitParams(t.params))return t;return{...t,params:toWireParams(t.params)}}function toWireStackItem(t){if(!shouldOmitParams(t.params))return t;return{...t,params:toWireParams(t.params)}}function getSitemapSnapshot(){const t=(0,_expoRouterStore.getRouteNodeMetadata)();return{routes:_RouteParser.RouteParser.parseRouteTree((0,_expoRouterStore.loadRouteNode)()),source:t.source,lastUpdatedAt:t.lastLoadedAt}}const routeEventsSyncAdapter=exports.routeEventsSyncAdapter={version:3,getSnapshot:()=>({events:_routeEventStore.routeEventStore.getEvents().map(toWireEvent),sitemap:getSitemapSnapshot(),stack:_navigationStackStore.navigationStackStore.getStack().map(toWireStackItem)}),subscribe:t=>{const a=_routeEventStore.routeEventStore.subscribeToEvents(t);const e=_navigationStackStore.navigationStackStore.subscribe(t);let r=null;if(!(0,_expoRouterStore.loadRouteNode)()){let o=0;const i=100;const n=()=>{o+=1;if((0,_expoRouterStore.loadRouteNode)()){r=null;t();return}r=o<i?setTimeout(n,100):null};r=setTimeout(n,100)}return()=>{a();e();if(r)clearTimeout(r)}},actions:{clearEvents:()=>{_routeEventStore.routeEventStore.clearEvents()},getCurrentRoute:()=>{const t=_routeEventStore.routeEventStore.getEvents()[0];if(t&&_routeEventStore.routeEventStore.isCapturing()){return{path:t.pathname,params:toWireParams(t.params),at:t.timestamp,source:"event"}}const a=_navigationStackStore.navigationStackStore.getStack();const e=a.find(r=>r.isFocused)??a[a.length-1];if(e?.pathname){return{path:e.pathname,params:toWireParams(e.params??{}),at:null,source:"stack"}}if(t){return{path:t.pathname,params:toWireParams(t.params),at:t.timestamp,source:"event",stale:true}}return{path:null,params:{},at:null,source:null}},navigate:t=>{const a=t;const e=a?.path;if(!e){throw new Error("navigate requires a 'path' param")}const r=(0,_sharedUi.getSafeRouter)();if(!r){const n=_navigationStackStore.navigationStackStore.getActions();const s=e.replace(/^\//,"");if(!n?.navigateToRoute||!s){throw new Error("expo-router is not available here and no navigation container was captured \u2014 is <RouteTracker /> mounted inside your NavigationContainer?")}const u=n.navigateToRoute(s,a?.params);if(!u){throw new Error(`Could not navigate to "${s}" \u2014 no navigation container is live.`)}return{navigated:e,replaced:false,via:"react-navigation"}}let o=[];try{o=getSitemapSnapshot().routes}catch{o=[]}if((0,_sitemapMatch.pathMatchesSitemap)(e,o)===false){throw new Error(`No screen matches "${e}". 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(a?.reset===true){try{if(r.canDismiss?.())r.dismissAll?.()}catch{}r.navigate(e);return{navigated:e,replaced:false,reset:true}}const i=a?.replace===true&&typeof r.replace==="function"?r.replace:r.navigate;i(e);return{navigated:e,replaced:a?.replace===true}},stackNavigateToIndex:t=>{const a=t?.index;if(typeof a!=="number"){throw new Error("stackNavigateToIndex requires a numeric 'index'")}const e=_navigationStackStore.navigationStackStore.getActions();if(!e)throw new Error("navigation stack is not available");e.navigateToIndex(a);return{navigatedToIndex:a}},stackPopToIndex:t=>{const a=t?.index;if(typeof a!=="number"){throw new Error("stackPopToIndex requires a numeric 'index'")}const e=_navigationStackStore.navigationStackStore.getActions();if(!e)throw new Error("navigation stack is not available");e.popToIndex(a);return{poppedToIndex:a}},stackGoBack:()=>{const t=_navigationStackStore.navigationStackStore.getActions();if(!t)throw new Error("navigation stack is not available");t.goBack();return{wentBack:true}},stackPopToTop:()=>{const t=_navigationStackStore.navigationStackStore.getActions();if(!t)throw new Error("navigation stack is not available");t.popToTop();return{poppedToTop:true}}}};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.pathMatchesSitemap=pathMatchesSitemap;function pathMatchesSitemap(a,l){const n=[];let o=false;const r=e=>{for(const t of e??[]){if(t.name?.includes("+not-found")||t.path?.includes("+not-found"))o=true;if(typeof t.path==="string")n.push(t.path);r(t.children)}};r(l);if(o||n.length===0)return void 0;const i=e=>"/"+e.split("?")[0].split("#")[0].split("/").filter(t=>t&&!/^\(.*\)$/.test(t)).join("/");const p=i(a);return n.some(e=>{const t=i(e);if(t===p)return true;const u=new RegExp("^"+t.split("/").map(s=>/^\[\.\.\..+\]$/.test(s)?".+":/^\[.+\]$/.test(s)?"[^/]+":s.replace(/[.*+?^${}()|\\]/g,"\\$&")).join("/")+"$");return u.test(p)})}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{getSafeRouter as
|
|
1
|
+
"use strict";import{getSafeRouter as g}from"@buoy-gg/shared-ui";import{pathMatchesSitemap as v}from"./sitemapMatch";import{routeEventStore as i}from"../stores/routeEventStore";import{navigationStackStore as o}from"../stores/navigationStackStore";import{RouteParser as h}from"../RouteParser";import{loadRouteNode as l,getRouteNodeMetadata as T}from"../expoRouterStore";import{isOverWireBudget as w}from"@buoy-gg/shared-ui";export const SNAPSHOT_PARAM_INLINE_LIMIT=16*1024;const k=Object.freeze({__buoyOmitted:"route-params",note:"Navigation params stay on the device."});function m(t){if(t==null)return false;return w(t,SNAPSHOT_PARAM_INLINE_LIMIT)}function c(t){if(!m(t))return t;return k}function E(t){if(!m(t.params))return t;return{...t,params:c(t.params)}}function b(t){if(!m(t.params))return t;return{...t,params:c(t.params)}}function d(){const t=T();return{routes:h.parseRouteTree(l()),source:t.source,lastUpdatedAt:t.lastLoadedAt}}export const routeEventsSyncAdapter={version:3,getSnapshot:()=>({events:i.getEvents().map(E),sitemap:d(),stack:o.getStack().map(b)}),subscribe:t=>{const a=i.subscribeToEvents(t);const e=o.subscribe(t);let r=null;if(!l()){let n=0;const u=100;const s=()=>{n+=1;if(l()){r=null;t();return}r=n<u?setTimeout(s,100):null};r=setTimeout(s,100)}return()=>{a();e();if(r)clearTimeout(r)}},actions:{clearEvents:()=>{i.clearEvents()},getCurrentRoute:()=>{const t=i.getEvents()[0];if(t&&i.isCapturing()){return{path:t.pathname,params:c(t.params),at:t.timestamp,source:"event"}}const a=o.getStack();const e=a.find(r=>r.isFocused)??a[a.length-1];if(e?.pathname){return{path:e.pathname,params:c(e.params??{}),at:null,source:"stack"}}if(t){return{path:t.pathname,params:c(t.params),at:t.timestamp,source:"event",stale:true}}return{path:null,params:{},at:null,source:null}},navigate:t=>{const a=t;const e=a?.path;if(!e){throw new Error("navigate requires a 'path' param")}const r=g();if(!r){const s=o.getActions();const p=e.replace(/^\//,"");if(!s?.navigateToRoute||!p){throw new Error("expo-router is not available here and no navigation container was captured \u2014 is <RouteTracker /> mounted inside your NavigationContainer?")}const f=s.navigateToRoute(p,a?.params);if(!f){throw new Error(`Could not navigate to "${p}" \u2014 no navigation container is live.`)}return{navigated:e,replaced:false,via:"react-navigation"}}let n=[];try{n=d().routes}catch{n=[]}if(v(e,n)===false){throw new Error(`No screen matches "${e}". 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(a?.reset===true){try{if(r.canDismiss?.())r.dismissAll?.()}catch{}r.navigate(e);return{navigated:e,replaced:false,reset:true}}const u=a?.replace===true&&typeof r.replace==="function"?r.replace:r.navigate;u(e);return{navigated:e,replaced:a?.replace===true}},stackNavigateToIndex:t=>{const a=t?.index;if(typeof a!=="number"){throw new Error("stackNavigateToIndex requires a numeric 'index'")}const e=o.getActions();if(!e)throw new Error("navigation stack is not available");e.navigateToIndex(a);return{navigatedToIndex:a}},stackPopToIndex:t=>{const a=t?.index;if(typeof a!=="number"){throw new Error("stackPopToIndex requires a numeric 'index'")}const e=o.getActions();if(!e)throw new Error("navigation stack is not available");e.popToIndex(a);return{poppedToIndex:a}},stackGoBack:()=>{const t=o.getActions();if(!t)throw new Error("navigation stack is not available");t.goBack();return{wentBack:true}},stackPopToTop:()=>{const t=o.getActions();if(!t)throw new Error("navigation stack is not available");t.popToTop();return{poppedToTop:true}}}};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";export function pathMatchesSitemap(l,c){const e=[];let o=false;const i=n=>{for(const t of n??[]){if(t.name?.includes("+not-found")||t.path?.includes("+not-found"))o=true;if(typeof t.path==="string")e.push(t.path);i(t.children)}};i(c);if(o||e.length===0)return void 0;const r=n=>"/"+n.split("?")[0].split("#")[0].split("/").filter(t=>t&&!/^\(.*\)$/.test(t)).join("/");const p=r(l);return e.some(n=>{const t=r(n);if(t===p)return true;const u=new RegExp("^"+t.split("/").map(s=>/^\[\.\.\..+\]$/.test(s)?".+":/^\[.+\]$/.test(s)?"[^/]+":s.replace(/[.*+?^${}()|\\]/g,"\\$&")).join("/")+"$");return u.test(p)})}
|
|
@@ -94,10 +94,17 @@ export declare const routeEventsSyncAdapter: {
|
|
|
94
94
|
navigated: string;
|
|
95
95
|
replaced: boolean;
|
|
96
96
|
via: string;
|
|
97
|
+
reset?: undefined;
|
|
97
98
|
} | {
|
|
98
99
|
navigated: string;
|
|
99
100
|
replaced: boolean;
|
|
101
|
+
reset: boolean;
|
|
100
102
|
via?: undefined;
|
|
103
|
+
} | {
|
|
104
|
+
navigated: string;
|
|
105
|
+
replaced: boolean;
|
|
106
|
+
via?: undefined;
|
|
107
|
+
reset?: undefined;
|
|
101
108
|
};
|
|
102
109
|
stackNavigateToIndex: (params?: unknown) => {
|
|
103
110
|
navigatedToIndex: number;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/** A sitemap node, as RouteParser emits it (only the fields the guard reads). */
|
|
2
|
+
export interface SitemapNode {
|
|
3
|
+
path?: string;
|
|
4
|
+
name?: string;
|
|
5
|
+
children?: SitemapNode[];
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Whether expo-router would find a screen for `path`, judged from the sitemap.
|
|
9
|
+
* `undefined` means "can't tell" (no sitemap, or the app has a +not-found
|
|
10
|
+
* screen, so an unknown path is handled in-app) — the caller then navigates.
|
|
11
|
+
*
|
|
12
|
+
* Why it exists: in an app with NO +not-found route, navigating to an unknown
|
|
13
|
+
* path replaces the root layout with expo-router's built-in "Unmatched Route"
|
|
14
|
+
* page. Buoy is mounted inside that layout, so one bad path unmounted Buoy and
|
|
15
|
+
* cut the app off from every tool until a reload (found by the BK route suite,
|
|
16
|
+
* "Open /promo/summer").
|
|
17
|
+
*/
|
|
18
|
+
export declare function pathMatchesSitemap(path: string, routes: SitemapNode[]): boolean | undefined;
|
|
19
|
+
//# sourceMappingURL=sitemapMatch.d.ts.map
|
package/lib/web/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
"use client";var It=Object.defineProperty;var bo=Object.getOwnPropertyDescriptor;var vo=Object.getOwnPropertyNames;var xo=Object.prototype.hasOwnProperty;var So=(e,t)=>{for(var o in t)It(e,o,{get:t[o],enumerable:true})},kt=(e,t,o,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of vo(t))!xo.call(e,a)&&a!==o&&It(e,a,{get:()=>t[a],enumerable:!(r=bo(t,a))||r.enumerable});return e},Co=(e,t,o)=>(kt(e,t,"default"),o&&kt(o,t,"default"));typeof window<"u"&&typeof globalThis.global>"u"&&(globalThis.global=globalThis);import{RoutesIcon as To}from"@buoy-gg/floating-tools-core/web";import{useState as we,useCallback as ue,useEffect as Bt,useRef as Ro,useMemo as Ie}from"react";var Dt={};So(Dt,{AccessibilityInfo:()=>Bo,ActivityIndicator:()=>xr,Alert:()=>_,Animated:()=>Do,AppRegistry:()=>Po,AppState:()=>Lo,Appearance:()=>Eo,BackHandler:()=>$o,Button:()=>Sr,CheckBox:()=>Jo,Clipboard:()=>Fo,DeviceEventEmitter:()=>cr,Dimensions:()=>zo,Easing:()=>Ao,FlatList:()=>Pt,I18nManager:()=>No,Image:()=>Qo,ImageBackground:()=>qo,InteractionManager:()=>jo,Keyboard:()=>Wo,KeyboardAvoidingView:()=>Zo,LayoutAnimation:()=>Oo,Linking:()=>Vo,LogBox:()=>lr,Modal:()=>br,NativeEventEmitter:()=>Ho,NativeModules:()=>ko,PanResponder:()=>Mo,Picker:()=>Xo,PixelRatio:()=>Uo,Platform:()=>Et,Pressable:()=>fr,ProgressBar:()=>Yo,RefreshControl:()=>er,SafeAreaView:()=>tr,ScrollView:()=>Ue,SectionList:()=>or,Share:()=>Go,StatusBar:()=>rr,StyleSheet:()=>ve,Switch:()=>vr,Text:()=>p,TextInput:()=>Lt,Touchable:()=>ar,TouchableHighlight:()=>gr,TouchableNativeFeedback:()=>nr,TouchableOpacity:()=>W,TouchableWithoutFeedback:()=>yr,UIManager:()=>Ko,Vibration:()=>_o,View:()=>l,VirtualizedList:()=>ir,YellowBox:()=>sr,findNodeHandle:()=>Cr,unstable_createElement:()=>Io,useColorScheme:()=>ur,useLocaleContext:()=>dr,useWindowDimensions:()=>pr});Co(Dt,wo);import*as wo from"react-native-web";import{unstable_createElement as Io,NativeModules as ko,AccessibilityInfo as Bo,Animated as Do,Appearance as Eo,AppRegistry as Po,AppState as Lo,BackHandler as $o,Clipboard as Fo,Dimensions as zo,Easing as Ao,I18nManager as No,Keyboard as Wo,InteractionManager as jo,LayoutAnimation as Oo,Linking as Vo,NativeEventEmitter as Ho,PanResponder as Mo,PixelRatio as Uo,Platform as Et,Share as Go,StyleSheet as ve,UIManager as Ko,Vibration as _o,CheckBox as Jo,FlatList as Pt,Image as Qo,ImageBackground as qo,KeyboardAvoidingView as Zo,Picker as Xo,ProgressBar as Yo,RefreshControl as er,SafeAreaView as tr,SectionList as or,StatusBar as rr,Touchable as ar,TouchableNativeFeedback as nr,VirtualizedList as ir,YellowBox as sr,LogBox as lr,DeviceEventEmitter as cr,useColorScheme as ur,useLocaleContext as dr,useWindowDimensions as pr}from"react-native-web";import*as Y from"react-native-web";import{createElement as mr,forwardRef as hr}from"react";function te(e){let t=hr((r,a)=>{let{accessibilityState:n,accessibilityValue:i,...u}=r;for(let c of["busy","checked","disabled","expanded","selected"])n?.[c]!==void 0&&u[`aria-${c}`]===void 0&&(u[`aria-${c}`]=n[c]);for(let[c,h]of Object.entries({min:"valuemin",max:"valuemax",now:"valuenow",text:"valuetext"}))i?.[c]!==void 0&&u[`aria-${h}`]===void 0&&(u[`aria-${h}`]=i[c]);return mr(e,{...u,ref:a})}),o=e.State;return o&&Object.assign(t,{State:o}),t.displayName=e.displayName??e.name??"NativeWebView",t}var l=te(Y.View),p=te(Y.Text),Lt=te(Y.TextInput),W=te(Y.TouchableOpacity),gr=te(Y.TouchableHighlight),yr=te(Y.TouchableWithoutFeedback),fr=te(Y.Pressable),Ue=te(Y.ScrollView),br=te(Y.Modal),vr=te(Y.Switch),xr=te(Y.ActivityIndicator),Sr=te(Y.Button),Cr=Y.findNodeHandle,_={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 h=document.createElement("p");h.textContent=t,h.style.cssText="line-height:1.5;white-space:pre-wrap;margin:0 0 20px",a.appendChild(h)}let i=document.createElement("div");i.style.cssText="display:flex;justify-content:flex-end;flex-wrap:wrap;gap:8px";let u=o?.length?o:[{text:"OK"}],c=()=>{a.close?.(),a.remove()};for(let h of u){let I=document.createElement("button");I.type="button",I.textContent=h.text??"OK",I.style.cssText=`padding:9px 14px;border:1px solid #64748b;border-radius:7px;color:white;background:${h.style==="destructive"?"#a52b38":"#283a4d"};cursor:pointer;font:inherit`,I.onclick=()=>{c(),h.onPress?.()},i.appendChild(I)}a.addEventListener("cancel",h=>{h.preventDefault(),r?.cancelable!==false&&(c(),r?.onDismiss?.())}),a.appendChild(i),document.body.appendChild(a),a.showModal?a.showModal():a.setAttribute("open","")}};import{browserRouter as Bn}from"@buoy-gg/shared-ui/web/utils";function Tr(){return null}import{useSafeRouter as Rr,isExpoRouterAvailable as wr,windowDragProps as Ir,ToolEmptyState as kr,resolveListEmptyState as Br,usePersistedState as at,monoFont as Ge}from"@buoy-gg/shared-ui/web";import{JsModal as Dr,ModalHeader as ie,TabSelector as Er,formatRelativeTime as Pr,devToolsStorageKeys as $e,Trash2 as Lr,Filter as $r,SearchBar as $t,ToolbarCopyButton as nt,Lock as Fr,ProUpgradeModal as zr,PowerToggleButton as Ar,buoyColors as Nr,night as M,TickProvider as Ft,useLimit as Wr}from"@buoy-gg/shared-ui/web";import{useIsPro as jr}from"@buoy-gg/license/web";import{useEventStoreEvents as Or}from"@buoy-gg/shared-ui/web";import{BaseEventStore as Vr,devToolsStorageKeys as Hr,persistentStorage as Mr}from"@buoy-gg/shared-ui/web";var zt=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 zt;var Ur=class extends Vr{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,Mr.getItem(Hr.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 Ur;function At(e={}){let{maxEvents:t=500,enabled:o=true}=e,{events:r,clearEvents:a,isActive:n}=Or(he,{maxEvents:t,enabled:o});return{events:r,clearEvents:a,isListening:n}}import{Navigation as Gr,night as Ke,monoFont as Kr}from"@buoy-gg/shared-ui/web";import{InlineCopyButton as ze,night as it,monoFont as st}from"@buoy-gg/shared-ui/web";import{DataViewer as _r}from"@buoy-gg/shared-ui/web/dataViewer";import{jsx as F,jsxs as J}from"react/jsx-runtime";function Jr(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 lt({event:e,visitNumber:t,routeTemplate:o}){let r=e.params&&Object.keys(e.params).length>0;return J(l,{style:x.container,children:[J(l,{style:x.section,children:[o&&J(l,{style:x.detailRow,testID:"buoy-routes-detail-template",children:[F(p,{style:x.detailLabel,children:"Template:"}),F(p,{style:x.detailValue,testID:"buoy-routes-detail-template-value",children:o}),F(ze,{value:o,buttonStyle:x.copyButton})]}),e.previousPathname&&J(l,{style:x.detailRow,testID:"buoy-routes-detail-from",children:[F(p,{style:x.detailLabel,children:"From:"}),F(p,{style:x.detailValue,testID:"buoy-routes-detail-from-value",children:e.previousPathname}),F(ze,{value:e.previousPathname,buttonStyle:x.copyButton})]}),J(l,{style:x.detailRow,testID:"buoy-routes-detail-to",children:[F(p,{style:x.detailLabel,children:"To:"}),F(p,{style:x.detailValue,testID:"buoy-routes-detail-to-value",children:e.pathname}),F(ze,{value:e.pathname,buttonStyle:x.copyButton})]})]}),J(l,{style:x.section,children:[e.timeSincePrevious!==void 0&&J(l,{style:x.detailRow,testID:"buoy-routes-detail-duration",children:[F(p,{style:x.detailLabel,children:"Duration:"}),F(p,{style:x.detailValue,testID:"buoy-routes-detail-duration-value",children:Jr(e.timeSincePrevious)})]}),J(l,{style:x.detailRow,testID:"buoy-routes-detail-time",children:[F(p,{style:x.detailLabel,children:"Time:"}),F(p,{style:x.detailValue,testID:"buoy-routes-detail-time-value",children:new Date(e.timestamp).toLocaleString()})]})]}),J(l,{style:x.section,children:[e.segments&&e.segments.length>0&&J(l,{style:x.detailRow,testID:"buoy-routes-detail-segments",children:[F(p,{style:x.detailLabel,children:"Segments:"}),F(p,{style:x.detailValue,testID:"buoy-routes-detail-segments-value",children:e.segments.join(" \u2192 ")}),F(ze,{value:JSON.stringify(e.segments),buttonStyle:x.copyButton})]}),r&&J(l,{style:x.dataViewerContainer,children:[J(l,{style:x.dataViewerHeader,children:[J(p,{style:x.dataViewerTitle,testID:"buoy-routes-detail-params-title",children:["Parameters (",Object.keys(e.params).length,")"]}),F(ze,{value:JSON.stringify(e.params,null,2),buttonStyle:x.copyButton})]}),F(_r,{data:e.params,title:"",showTypeFilter:true,rawMode:true,initialExpanded:true})]}),t>1&&J(l,{style:x.detailRow,testID:"buoy-routes-detail-visited",children:[F(p,{style:x.detailLabel,children:"Visited:"}),J(p,{style:x.detailValue,testID:"buoy-routes-detail-visited-value",children:[t," time",t!==1?"s":""]})]})]})]})}var x=ve.create({container:{gap:12},section:{gap:8},detailRow:{flexDirection:"row",alignItems:"center",gap:8},detailLabel:{fontSize:10,color:it.color.textSecondary,fontFamily:st,fontWeight:"600",minWidth:70},detailValue:{fontSize:11,color:it.color.text,fontFamily:st,flex:1},copyButton:{padding:4,borderRadius:4},dataViewerContainer:{marginTop:4},dataViewerHeader:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",marginBottom:8},dataViewerTitle:{fontSize:11,color:it.color.textSecondary,fontFamily:st,fontWeight:"600"}});function ct(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 Nt(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(u=>o.has(String(u)))))for(let u of i)r.push(`${encodeURIComponent(a)}=${encodeURIComponent(String(u))}`)}return r.length?`${e}?${r.join("&")}`:e}function Qr(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 Ae,jsxs as Wt}from"react/jsx-runtime";function jt({event:e,visitNumber:t=1,onNavigate:o}){let r=ct(e.pathname,e.segments);return Wt(l,{style:ke.container,children:[Ae(Ue,{testID:"buoy-routes-detail-scroll",style:ke.scroll,contentContainerStyle:ke.scrollContent,showsVerticalScrollIndicator:true,children:Ae(lt,{event:e,visitNumber:t,routeTemplate:r})}),o&&Ae(l,{style:ke.footer,children:Wt(W,{style:ke.goButton,onPress:()=>o(Nt(e.pathname,e.params)),activeOpacity:.8,testID:"buoy-routes-detail-go",accessibilityRole:"button",accessibilityLabel:`Go to route ${e.pathname}`,children:[Ae(Gr,{size:16,color:Ke.color.onAccent}),Ae(p,{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:Ke.color.border},goButton:{flexDirection:"row",alignItems:"center",justifyContent:"center",gap:8,backgroundColor:Ke.color.accent,paddingVertical:12,borderRadius:8},goButtonText:{fontSize:13,fontWeight:"600",color:Ke.color.onAccent,fontFamily:Kr,textTransform:"uppercase",letterSpacing:.5}});import{Filter as Ot,DynamicFilterView as qr}from"@buoy-gg/shared-ui/web";import{jsx as Zr}from"react/jsx-runtime";function Xr({ignoredPatterns:e,onTogglePattern:t,onAddPattern:o,availablePathnames:r=[]}){return Zr(qr,{...{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 Ne,useMemo as _e,useEffect as Yr}from"react";import{night as y,ToolEmptyState as ea,monoFont as U}from"@buoy-gg/shared-ui/web";import{useSafeRouter as ta}from"@buoy-gg/shared-ui/web";import{Search as Vt,ChevronDown as Ht,ChevronRight as Mt,Home as oa,InlineCopyButton as ra,CopyButton as aa,RefreshCw as na,formatRelativeTime as ia,ProUpgradeModal as sa}from"@buoy-gg/shared-ui/web";import{useIsPro as la}from"@buoy-gg/license/web";import{useState as ca,useEffect as Ut,useMemo as Se,useCallback as ua}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),n=this.detectRouteType(e),i=this.shouldIncludeRoute(e),u={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(u);for(let c of e.children)this.traverseNode(c,a,i?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(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(
|
|
1
|
+
"use client";var It=Object.defineProperty;var vo=Object.getOwnPropertyDescriptor;var xo=Object.getOwnPropertyNames;var So=Object.prototype.hasOwnProperty;var Co=(e,t)=>{for(var o in t)It(e,o,{get:t[o],enumerable:true})},kt=(e,t,o,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of xo(t))!So.call(e,a)&&a!==o&&It(e,a,{get:()=>t[a],enumerable:!(r=vo(t,a))||r.enumerable});return e},To=(e,t,o)=>(kt(e,t,"default"),o&&kt(o,t,"default"));typeof window<"u"&&typeof globalThis.global>"u"&&(globalThis.global=globalThis);import{RoutesIcon as Ro}from"@buoy-gg/floating-tools-core/web";import{useState as we,useCallback as ue,useEffect as Bt,useRef as wo,useMemo as Ie}from"react";var Dt={};Co(Dt,{AccessibilityInfo:()=>Do,ActivityIndicator:()=>Sr,Alert:()=>_,Animated:()=>Eo,AppRegistry:()=>Lo,AppState:()=>$o,Appearance:()=>Po,BackHandler:()=>Fo,Button:()=>Cr,CheckBox:()=>Qo,Clipboard:()=>zo,DeviceEventEmitter:()=>ur,Dimensions:()=>Ao,Easing:()=>No,FlatList:()=>Pt,I18nManager:()=>Wo,Image:()=>qo,ImageBackground:()=>Zo,InteractionManager:()=>Vo,Keyboard:()=>jo,KeyboardAvoidingView:()=>Xo,LayoutAnimation:()=>Oo,Linking:()=>Ho,LogBox:()=>cr,Modal:()=>vr,NativeEventEmitter:()=>Mo,NativeModules:()=>Bo,PanResponder:()=>Uo,Picker:()=>Yo,PixelRatio:()=>Go,Platform:()=>Et,Pressable:()=>br,ProgressBar:()=>er,RefreshControl:()=>tr,SafeAreaView:()=>or,ScrollView:()=>Ue,SectionList:()=>rr,Share:()=>Ko,StatusBar:()=>ar,StyleSheet:()=>ve,Switch:()=>xr,Text:()=>p,TextInput:()=>Lt,Touchable:()=>nr,TouchableHighlight:()=>yr,TouchableNativeFeedback:()=>ir,TouchableOpacity:()=>W,TouchableWithoutFeedback:()=>fr,UIManager:()=>_o,Vibration:()=>Jo,View:()=>c,VirtualizedList:()=>sr,YellowBox:()=>lr,findNodeHandle:()=>Tr,unstable_createElement:()=>ko,useColorScheme:()=>dr,useLocaleContext:()=>pr,useWindowDimensions:()=>mr});To(Dt,Io);import*as Io from"react-native-web";import{unstable_createElement as ko,NativeModules as Bo,AccessibilityInfo as Do,Animated as Eo,Appearance as Po,AppRegistry as Lo,AppState as $o,BackHandler as Fo,Clipboard as zo,Dimensions as Ao,Easing as No,I18nManager as Wo,Keyboard as jo,InteractionManager as Vo,LayoutAnimation as Oo,Linking as Ho,NativeEventEmitter as Mo,PanResponder as Uo,PixelRatio as Go,Platform as Et,Share as Ko,StyleSheet as ve,UIManager as _o,Vibration as Jo,CheckBox as Qo,FlatList as Pt,Image as qo,ImageBackground as Zo,KeyboardAvoidingView as Xo,Picker as Yo,ProgressBar as er,RefreshControl as tr,SafeAreaView as or,SectionList as rr,StatusBar as ar,Touchable as nr,TouchableNativeFeedback as ir,VirtualizedList as sr,YellowBox as lr,LogBox as cr,DeviceEventEmitter as ur,useColorScheme as dr,useLocaleContext as pr,useWindowDimensions as mr}from"react-native-web";import*as Y from"react-native-web";import{createElement as hr,forwardRef as gr}from"react";function te(e){let t=gr((r,a)=>{let{accessibilityState:i,accessibilityValue:n,...u}=r;for(let s of["busy","checked","disabled","expanded","selected"])i?.[s]!==void 0&&u[`aria-${s}`]===void 0&&(u[`aria-${s}`]=i[s]);for(let[s,m]of Object.entries({min:"valuemin",max:"valuemax",now:"valuenow",text:"valuetext"}))n?.[s]!==void 0&&u[`aria-${m}`]===void 0&&(u[`aria-${m}`]=n[s]);return hr(e,{...u,ref:a})}),o=e.State;return o&&Object.assign(t,{State:o}),t.displayName=e.displayName??e.name??"NativeWebView",t}var c=te(Y.View),p=te(Y.Text),Lt=te(Y.TextInput),W=te(Y.TouchableOpacity),yr=te(Y.TouchableHighlight),fr=te(Y.TouchableWithoutFeedback),br=te(Y.Pressable),Ue=te(Y.ScrollView),vr=te(Y.Modal),xr=te(Y.Switch),Sr=te(Y.ActivityIndicator),Cr=te(Y.Button),Tr=Y.findNodeHandle,_={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 m=document.createElement("p");m.textContent=t,m.style.cssText="line-height:1.5;white-space:pre-wrap;margin:0 0 20px",a.appendChild(m)}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"}],s=()=>{a.close?.(),a.remove()};for(let m of u){let I=document.createElement("button");I.type="button",I.textContent=m.text??"OK",I.style.cssText=`padding:9px 14px;border:1px solid #64748b;border-radius:7px;color:white;background:${m.style==="destructive"?"#a52b38":"#283a4d"};cursor:pointer;font:inherit`,I.onclick=()=>{s(),m.onPress?.()},n.appendChild(I)}a.addEventListener("cancel",m=>{m.preventDefault(),r?.cancelable!==false&&(s(),r?.onDismiss?.())}),a.appendChild(n),document.body.appendChild(a),a.showModal?a.showModal():a.setAttribute("open","")}};import{browserRouter as Dn}from"@buoy-gg/shared-ui/web/utils";function Rr(){return null}import{useSafeRouter as wr,isExpoRouterAvailable as Ir,windowDragProps as kr,ToolEmptyState as Br,resolveListEmptyState as Dr,usePersistedState as at,monoFont as Ge}from"@buoy-gg/shared-ui/web";import{JsModal as Er,ModalHeader as ie,TabSelector as Pr,formatRelativeTime as Lr,devToolsStorageKeys as $e,Trash2 as $r,Filter as Fr,SearchBar as $t,ToolbarCopyButton as nt,Lock as zr,ProUpgradeModal as Ar,PowerToggleButton as Nr,buoyColors as Wr,night as M,TickProvider as Ft,useLimit as jr}from"@buoy-gg/shared-ui/web";import{useIsPro as Vr}from"@buoy-gg/license/web";import{useEventStoreEvents as Or}from"@buoy-gg/shared-ui/web";import{BaseEventStore as Hr,devToolsStorageKeys as Mr,persistentStorage as Ur}from"@buoy-gg/shared-ui/web";var zt=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 zt;var Gr=class extends Hr{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,Ur.getItem(Mr.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 Gr;function At(e={}){let{maxEvents:t=500,enabled:o=true}=e,{events:r,clearEvents:a,isActive:i}=Or(he,{maxEvents:t,enabled:o});return{events:r,clearEvents:a,isListening:i}}import{Navigation as Kr,night as Ke,monoFont as _r}from"@buoy-gg/shared-ui/web";import{InlineCopyButton as ze,night as it,monoFont as st}from"@buoy-gg/shared-ui/web";import{DataViewer as Jr}from"@buoy-gg/shared-ui/web/dataViewer";import{jsx as F,jsxs as J}from"react/jsx-runtime";function Qr(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 lt({event:e,visitNumber:t,routeTemplate:o}){let r=e.params&&Object.keys(e.params).length>0;return J(c,{style:x.container,children:[J(c,{style:x.section,children:[o&&J(c,{style:x.detailRow,testID:"buoy-routes-detail-template",children:[F(p,{style:x.detailLabel,children:"Template:"}),F(p,{style:x.detailValue,testID:"buoy-routes-detail-template-value",children:o}),F(ze,{value:o,buttonStyle:x.copyButton})]}),e.previousPathname&&J(c,{style:x.detailRow,testID:"buoy-routes-detail-from",children:[F(p,{style:x.detailLabel,children:"From:"}),F(p,{style:x.detailValue,testID:"buoy-routes-detail-from-value",children:e.previousPathname}),F(ze,{value:e.previousPathname,buttonStyle:x.copyButton})]}),J(c,{style:x.detailRow,testID:"buoy-routes-detail-to",children:[F(p,{style:x.detailLabel,children:"To:"}),F(p,{style:x.detailValue,testID:"buoy-routes-detail-to-value",children:e.pathname}),F(ze,{value:e.pathname,buttonStyle:x.copyButton})]})]}),J(c,{style:x.section,children:[e.timeSincePrevious!==void 0&&J(c,{style:x.detailRow,testID:"buoy-routes-detail-duration",children:[F(p,{style:x.detailLabel,children:"Duration:"}),F(p,{style:x.detailValue,testID:"buoy-routes-detail-duration-value",children:Qr(e.timeSincePrevious)})]}),J(c,{style:x.detailRow,testID:"buoy-routes-detail-time",children:[F(p,{style:x.detailLabel,children:"Time:"}),F(p,{style:x.detailValue,testID:"buoy-routes-detail-time-value",children:new Date(e.timestamp).toLocaleString()})]})]}),J(c,{style:x.section,children:[e.segments&&e.segments.length>0&&J(c,{style:x.detailRow,testID:"buoy-routes-detail-segments",children:[F(p,{style:x.detailLabel,children:"Segments:"}),F(p,{style:x.detailValue,testID:"buoy-routes-detail-segments-value",children:e.segments.join(" \u2192 ")}),F(ze,{value:JSON.stringify(e.segments),buttonStyle:x.copyButton})]}),r&&J(c,{style:x.dataViewerContainer,children:[J(c,{style:x.dataViewerHeader,children:[J(p,{style:x.dataViewerTitle,testID:"buoy-routes-detail-params-title",children:["Parameters (",Object.keys(e.params).length,")"]}),F(ze,{value:JSON.stringify(e.params,null,2),buttonStyle:x.copyButton})]}),F(Jr,{data:e.params,title:"",showTypeFilter:true,rawMode:true,initialExpanded:true})]}),t>1&&J(c,{style:x.detailRow,testID:"buoy-routes-detail-visited",children:[F(p,{style:x.detailLabel,children:"Visited:"}),J(p,{style:x.detailValue,testID:"buoy-routes-detail-visited-value",children:[t," time",t!==1?"s":""]})]})]})]})}var x=ve.create({container:{gap:12},section:{gap:8},detailRow:{flexDirection:"row",alignItems:"center",gap:8},detailLabel:{fontSize:10,color:it.color.textSecondary,fontFamily:st,fontWeight:"600",minWidth:70},detailValue:{fontSize:11,color:it.color.text,fontFamily:st,flex:1},copyButton:{padding:4,borderRadius:4},dataViewerContainer:{marginTop:4},dataViewerHeader:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",marginBottom:8},dataViewerTitle:{fontSize:11,color:it.color.textSecondary,fontFamily:st,fontWeight:"600"}});function ct(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 Nt(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 qr(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 Ae,jsxs as Wt}from"react/jsx-runtime";function jt({event:e,visitNumber:t=1,onNavigate:o}){let r=ct(e.pathname,e.segments);return Wt(c,{style:ke.container,children:[Ae(Ue,{testID:"buoy-routes-detail-scroll",style:ke.scroll,contentContainerStyle:ke.scrollContent,showsVerticalScrollIndicator:true,children:Ae(lt,{event:e,visitNumber:t,routeTemplate:r})}),o&&Ae(c,{style:ke.footer,children:Wt(W,{style:ke.goButton,onPress:()=>o(Nt(e.pathname,e.params)),activeOpacity:.8,testID:"buoy-routes-detail-go",accessibilityRole:"button",accessibilityLabel:`Go to route ${e.pathname}`,children:[Ae(Kr,{size:16,color:Ke.color.onAccent}),Ae(p,{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:Ke.color.border},goButton:{flexDirection:"row",alignItems:"center",justifyContent:"center",gap:8,backgroundColor:Ke.color.accent,paddingVertical:12,borderRadius:8},goButtonText:{fontSize:13,fontWeight:"600",color:Ke.color.onAccent,fontFamily:_r,textTransform:"uppercase",letterSpacing:.5}});import{Filter as Vt,DynamicFilterView as Zr}from"@buoy-gg/shared-ui/web";import{jsx as Xr}from"react/jsx-runtime";function Yr({ignoredPatterns:e,onTogglePattern:t,onAddPattern:o,availablePathnames:r=[]}){return Xr(Zr,{...{addFilterSection:{enabled:true,placeholder:"Enter pattern (e.g., /_sitemap)",title:"ACTIVE FILTERS",icon:Vt},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:Vt},onPatternToggle:t,onPatternAdd:o,activePatterns:e}})}import{useState as Be,useCallback as Ne,useMemo as _e,useEffect as ea}from"react";import{night as y,ToolEmptyState as ta,monoFont as U}from"@buoy-gg/shared-ui/web";import{useSafeRouter as oa}from"@buoy-gg/shared-ui/web";import{Search as Ot,ChevronDown as Ht,ChevronRight as Mt,Home as ra,InlineCopyButton as aa,CopyButton as na,RefreshCw as ia,formatRelativeTime as sa,ProUpgradeModal as la}from"@buoy-gg/shared-ui/web";import{useIsPro as ca}from"@buoy-gg/license/web";import{useState as ua,useEffect as Ut,useMemo as Se,useCallback as da}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 s of e.children)this.traverseNode(s,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(n=>n.path===t))return o;let a=t.split("/").filter(Boolean),i="";for(let n=0;n<a.length-1;n++){i+="/"+a[n];let u=r.find(s=>s.path===i);u&&o.push(u)}return o}};import{getBrowserHref as pa}from"@buoy-gg/shared-ui/web/utils";var De=new Map,ut=null;function ma(e){for(let o of e)De.set(o,(De.get(o)??0)+1);ut=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)}ut=Date.now()}}}function ha(){return[...De.keys()]}function ga(){return ut}function dt(){return typeof window<"u"}function We(){return dt()?{route:"",type:"layout",contextKey:"browser",children:[...new Set([...ha(),new URL(pa()).pathname])].map(e=>({route:e.replace(/^\//,"")||"index",type:"route",contextKey:e,children:[],dynamic:null}))}:null}function pt(){return{source:null,lastLoadedAt:ga()}}function Je(e={}){let{searchQuery:t="",sortBy:o="path",autoRefresh:r=false,refreshInterval:a=1e3,injectedRoutes:i,injectedSource:n=null,injectedLastUpdatedAt:u=null}=e,s=i!=null,[m,I]=ua(()=>{let R=We(),O=pt();return{node:R,version:0,lastUpdatedAt:O.lastLoadedAt,source:O.source}}),v=m.node,T=m.version,$=m.lastUpdatedAt,ae=m.source,V=da(()=>{I(R=>{let O=We(),K=pt();return{node:O,version:R.version+1,lastUpdatedAt:K.lastLoadedAt,source:K.source}})},[]);Ut(()=>{if(v||s||!dt())return;let R=0,O=100,K=()=>{R++,V(),R<O&&(z=setTimeout(K,100))},z=setTimeout(K,100);return()=>clearTimeout(z)},[v,V,s]),Ut(()=>{if(!r)return;let R=setInterval(V,a);return()=>clearInterval(R)},[r,a,V]);let N=s?i.length>0:!!v,P=s?true:dt(),D=Se(()=>s?i:v?ge.parseRouteTree(v):[],[v,T,s,i]),ee=Se(()=>ge.sortRoutes(D,o),[D,o]),k=Se(()=>t?ge.filterRoutes(ee,t):ee,[ee,t]),G=Se(()=>ge.organizeRoutes(k),[k]),pe=Se(()=>ge.getRouteStats(D),[D]);return{routes:ee,groups:G,stats:pe,filteredRoutes:k,isLoaded:N,isSupported:P,refresh:V,findRoute:R=>ge.findRouteByPath(D,R),getParents:R=>ge.getParentRoutes(D,R),lastUpdatedAt:s?u:$,source:s?n:ae}}function ya(e){let{findRoute:t}=Je();return Se(()=>t(e),[t,e])}function fa(e){let{getParents:t}=Je();return Se(()=>t(e),[t,e])}function mt(e){return String(e).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"root"}function ba(e,t){return`buoy-routes-event-row-${mt(e)}-${t}`}function va(e){return`buoy-routes-route-${mt(e)}`}function Gt(e){return`buoy-routes-group-${mt(e)}`}function xa(e){return`buoy-routes-stack-item-${e}`}import{jsx as d,jsxs as L}from"react/jsx-runtime";var Z=Et.OS==="web",Qe=Z?22:16,Sa={path:"/",name:"index",type:"index",params:[],nodeType:"route",contextKey:"/",isInternal:false,children:[],depth:0};function ht({style:e,injectedRoutes:t,injectedSource:o,injectedLastUpdatedAt:r,onNavigateRoute:a}){let[i,n]=Be(""),[u,s]=Be(false),[m,I]=Be(new Set(["Static Routes","Dynamic Routes"])),[v,T]=Be(false),[$,ae]=Be(false),V=ca();ea(()=>{$&&V&&ae(false)},[$,V]);let N=oa(),{groups:P,stats:D,isLoaded:ee,isSupported:k,filteredRoutes:G,routes:pe,refresh:R,lastUpdatedAt:O,source:K}=Je({searchQuery:i,sortBy:"path",injectedRoutes:t,injectedSource:o,injectedLastUpdatedAt:r}),z=_e(()=>({summary:{total:D.total,static:D.static,dynamic:D.dynamic,layouts:D.layouts,groups:D.groups,timestamp:new Date().toISOString()},groups:P.map(b=>({title:b.title,description:b.description,count:b.routes.length,routes:b.routes.map(w=>({path:w.path,name:w.name,type:w.type,params:w.params,depth:w.depth,hasChildren:w.children.length>0,childrenCount:w.children.length}))})),allRoutes:pe.map(b=>b.path)}),[P,D,pe]),Ce=Ne(b=>{I(w=>{let X=new Set(w);return X.has(b)?X.delete(b):X.add(b),X})},[]),ye=Ne((b,w=0,X={})=>{let Pe=b.params;if(w>=Pe.length){let ne=b.path;Object.entries(X).forEach(([fe,He])=>{b.type==="catch-all"?ne=ne.replace(`[...${fe}]`,He):ne=ne.replace(`[${fe}]`,He)});try{N.push(ne)}catch(fe){_.alert("Navigation Error",String(fe))}return}let Le=Pe[w],et=b.type==="catch-all"?`[...${Le}]`:`[${Le}]`;_.prompt("Enter Parameter Value",`Enter value for ${et}:
|
|
3
3
|
|
|
4
|
-
Route: ${b.path}`,[{text:"Cancel",style:"cancel"},{text:w<Pe.length-1?"Next":"Navigate",onPress:ne=>{if(ne&&ne.trim()){let fe={...X,[Le]:ne.trim()};ye(b,w+1,fe)}else _.alert("Invalid Value","Please enter a value for the parameter")}}],"plain-text")},[N]),xe=Ne((b,w)=>{if(a){a(b);return}if(!O&&!w?.bypassPro){ae(true);return}if(b.type==="layout"||b.type==="group"){_.alert("Cannot Navigate",`${b.type==="layout"?"Layouts":"Route groups"} are not navigable routes`);return}if(b.type==="dynamic"||b.type==="catch-all"){if(b.params.length===0){try{N.push(b.path)}catch(X){_.alert("Navigation Error",String(X))}return}ye(b);return}try{N.push(b.path)}catch(X){_.alert("Navigation Error",String(X))}},[N,ye,O,a]),le=Ne(()=>{xe(xa,{bypassPro:true})},[xe]),f=Ne(()=>{v||(T(true),R(),setTimeout(()=>T(false),400))},[v,R]),E=_e(()=>V?`Updated ${ia(V)}`:"Awaiting route data",[V]),H=_e(()=>K?`Source: ${K}`:"Source: unknown",[K]),ce=_e(()=>n&&G.length>0?[{title:"Search Results",icon:"",routes:G}]:P,[n,G,P]);return ee?L(l,{style:[s.container,e],children:[u&&L(l,{style:s.searchContainer,testID:"buoy-routes-sitemap-search-field",children:[d(Vt,{size:16,color:y.color.textTertiary}),d(Lt,{style:s.searchInput,placeholder:"Search routes...",placeholderTextColor:y.color.placeholder,value:n,onChangeText:i,autoCapitalize:"none",autoCorrect:false,autoFocus:true,testID:"buoy-routes-sitemap-search",accessibilityLabel:"Search routes"}),n.length>0&&d(W,{onPress:()=>i(""),style:s.clearButton,testID:"buoy-routes-sitemap-search-clear",accessibilityRole:"button",accessibilityLabel:"Clear route search",children:d(p,{style:s.clearButtonText,children:"\u2715"})}),d(W,{style:s.closeSearchButton,onPress:()=>{c(false),i("")},testID:"buoy-routes-sitemap-search-done",accessibilityRole:"button",accessibilityLabel:"Done searching routes",children:d(p,{style:s.closeSearchText,children:"Done"})})]}),L(Ue,{testID:"buoy-routes-sitemap-scroll",style:s.scrollView,contentContainerStyle:s.scrollContent,children:[!u&&L(l,{style:s.header,children:[L(l,{style:s.actionsRow,children:[L(l,{style:[s.actionWrapper,Z&&s.actionWrapperDesktop],children:[d(W,{style:[s.iconButton,Z&&s.iconButtonDesktop],onPress:le,accessibilityLabel:"Go to home route",accessibilityRole:"button",testID:"buoy-routes-sitemap-home",children:d(oa,{size:Qe,color:y.color.textSecondary})}),d(p,{style:[s.actionLabel,Z&&s.actionLabelDesktop],children:"Home"})]}),L(l,{style:[s.actionWrapper,Z&&s.actionWrapperDesktop],children:[d(aa,{value:z,testID:"buoy-routes-sitemap-copy",size:Z?Qe:14,buttonStyle:Z?s.actionButtonHeaderDesktop:s.actionButtonHeader}),d(p,{style:[s.actionLabel,Z&&s.actionLabelDesktop],children:"Copy"})]}),L(l,{style:[s.actionWrapper,Z&&s.actionWrapperDesktop],children:[d(W,{style:[s.iconButton,Z&&s.iconButtonDesktop,v&&s.refreshButtonDisabled],onPress:f,disabled:v,testID:"buoy-routes-sitemap-refresh",accessibilityRole:"button",accessibilityLabel:"Refresh route tree",children:d(na,{size:Qe,color:v?y.color.textTertiary:y.color.textSecondary})}),d(p,{style:[s.actionLabel,Z&&s.actionLabelDesktop],children:"Refresh"})]}),L(l,{style:[s.actionWrapper,Z&&s.actionWrapperDesktop],children:[d(W,{style:[s.iconButton,Z&&s.iconButtonDesktop],onPress:()=>c(true),testID:"buoy-routes-sitemap-search-open",accessibilityRole:"button",accessibilityLabel:"Search routes",children:d(Vt,{size:Qe,color:y.color.textSecondary})}),d(p,{style:[s.actionLabel,Z&&s.actionLabelDesktop],children:"Search"})]})]}),L(l,{style:s.statsGrid,children:[d(Ee,{value:D.total,label:"Total",id:"total"}),d(Ee,{value:D.static,label:"Static",id:"static"}),d(Ee,{value:D.dynamic,label:"Dynamic",id:"dynamic"}),d(Ee,{value:D.catchAll,label:"Catch-All",id:"catch-all"}),d(Ee,{value:D.layouts,label:"Layouts",id:"layouts"}),d(Ee,{value:D.groups,label:"Groups",id:"groups"})]})]}),ce.length===0?d(ea,{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(b=>d(Sa,{group:b,isExpanded:n.length>0||h.has(b.title),onToggleExpand:()=>Ce(b.title),onNavigate:xe},b.title)),L(l,{style:s.metaFooter,children:[d(p,{style:s.metaText,testID:"buoy-routes-sitemap-updated",children:E}),d(l,{style:s.sourceBadge,children:d(p,{style:s.sourceText,testID:"buoy-routes-sitemap-source",children:H})})]})]}),d(sa,{visible:$,onClose:()=>ae(false),featureName:"Route Navigation"})]}):d(l,{style:[s.container,e],children:d(l,{style:s.loadingContainer,children:d(p,{style:s.loadingText,testID:"buoy-routes-sitemap-loading",children:k?"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 L(l,{style:s.statItem,testID:`buoy-routes-stat-${o}`,accessibilityLabel:`${t}, ${e}`,children:[d(p,{style:s.statValue,testID:`buoy-routes-stat-${o}-value`,children:e}),d(p,{style:s.statLabel,children:t})]})}function Sa({group:e,isExpanded:t,onToggleExpand:o,onNavigate:r}){return L(l,{style:s.groupContainer,children:[L(W,{style:s.groupHeader,onPress:o,activeOpacity:.7,testID:Gt(e.title),accessibilityRole:"button",accessibilityLabel:`${e.title}, ${e.routes.length} routes`,children:[L(l,{style:s.groupHeaderLeft,children:[t?d(Ht,{size:14,color:y.color.textSecondary}):d(Mt,{size:14,color:y.color.textSecondary}),d(p,{style:s.groupTitle,children:e.title})]}),d(l,{style:s.groupBadge,children:d(p,{style:s.groupCount,testID:`${Gt(e.title)}-count`,children:e.routes.length})})]}),e.description&&d(l,{style:s.groupDescription,children:d(p,{style:s.groupDescriptionText,children:e.description})}),t&&d(l,{style:s.routesList,children:e.routes.map((a,n)=>d(Kt,{route:a,onNavigate:r},`${a.path}-${n}`))})]})}function Kt({route:e,depth:t=0,onNavigate:o}){let[r,a]=Be(false),n=e.children.length>0,i=Ca(e.type),u=e.type!=="layout"&&e.type!=="group",c=ba(e.path),h=n,I=h?r:true;return d(l,{style:[s.routeItem,{marginLeft:t*12}],testID:c,children:L(l,{style:s.routeCard,children:[L(l,{style:s.routeHeader,children:[h?L(W,{style:s.routeHeaderLeft,onPress:()=>a(!r),activeOpacity:.7,testID:`${c}-toggle`,accessibilityRole:"button",accessibilityLabel:`${e.path}, ${e.type}, ${e.children.length} nested`,children:[d(l,{style:s.expandIndicator,children:r?d(Ht,{size:14,color:y.color.textSecondary}):d(Mt,{size:14,color:y.color.textSecondary})}),d(p,{style:s.routePath,numberOfLines:3,testID:`${c}-path`,children:e.path})]}):L(l,{style:s.routeHeaderLeft,accessible:true,accessibilityLabel:`${e.path}, ${e.type}`,children:[d(l,{style:s.expandIndicator}),d(p,{style:s.routePath,numberOfLines:3,testID:`${c}-path`,children:e.path})]}),L(l,{style:s.routeHeaderActions,children:[n&&d(l,{style:s.childCountBadge,children:d(p,{style:s.childCountText,testID:`${c}-children-count`,children:e.children.length})}),d(l,{style:[s.typeTag,{backgroundColor:`${i}15`,borderColor:`${i}40`}],children:d(p,{style:[s.typeText,{color:i}],testID:`${c}-type`,children:e.type.toUpperCase()})}),d(ra,{value:e.path,buttonStyle:s.iconAction,testID:`${c}-copy`}),u&&d(W,{style:s.goButton,onPress:()=>o(e),activeOpacity:.7,testID:`${c}-go`,accessibilityRole:"button",accessibilityLabel:`Go to ${e.path}`,children:d(p,{style:s.goButtonText,children:"Go"})})]})]}),I&&n&&d(l,{style:s.childrenContainer,children:e.children.map((v,T)=>d(Kt,{route:v,depth:t+1,onNavigate:o},`${v.path}-${T}`))})]})})}function Ca(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:y.color.textSecondary,fontSize:14,fontFamily:U,textAlign:"center",lineHeight:20,paddingHorizontal:32,maxWidth:420},header:{flexDirection:"column",padding:8,borderBottomWidth:1,borderBottomColor:y.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:y.color.surface,borderRadius:8,paddingVertical:10,paddingHorizontal:12,alignItems:"center"},statValue:{fontSize:18,fontWeight:"800",color:y.color.text,fontFamily:U},statLabel:{fontSize:10,color:y.color.textTertiary,marginTop:4,fontFamily:U,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:y.color.surfaceElevated},actionButtonHeaderDesktop:{padding:12,borderRadius:8,backgroundColor:y.color.surfaceElevated},iconButton:{padding:6,borderRadius:4,alignItems:"center",justifyContent:"center"},iconButtonDesktop:{padding:12,borderRadius:8,backgroundColor:y.color.surfaceElevated},actionLabel:{fontSize:8,color:y.color.textTertiary,fontFamily:U,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:y.color.border},metaText:{fontSize:12,color:y.color.textSecondary,fontFamily:U},sourceBadge:{paddingHorizontal:8,paddingVertical:2,borderRadius:999,borderWidth:1,borderColor:y.color.border,backgroundColor:y.color.surface},sourceText:{fontSize:11,color:y.color.textSecondary,textTransform:"capitalize",fontFamily:U},searchContainer:{flexDirection:"row",alignItems:"center",padding:8,gap:8,borderBottomWidth:1,borderBottomColor:y.color.border},searchInput:{flex:1,color:y.color.text,fontSize:14,fontFamily:U},clearButton:{padding:4},clearButtonText:{color:y.color.textTertiary,fontSize:18},closeSearchButton:{paddingHorizontal:8,paddingVertical:4},closeSearchText:{color:y.color.accent,fontSize:14,fontWeight:"600",fontFamily:U},scrollView:{flex:1},scrollContent:{paddingBottom:8},emptyState:{padding:32,alignItems:"center"},emptyText:{color:y.color.textSecondary,fontSize:14,fontFamily:U},groupContainer:{marginVertical:4},groupHeader:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",padding:12,paddingHorizontal:16,backgroundColor:y.color.surface,borderLeftWidth:3,borderLeftColor:y.color.fillTertiary},groupHeaderLeft:{flexDirection:"row",alignItems:"center",gap:8,flex:1},groupTitle:{fontSize:12,fontWeight:"700",color:y.color.text,fontFamily:U,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:U},routesList:{backgroundColor:"transparent"},groupDescription:{paddingHorizontal:16,paddingVertical:8,marginBottom:8,backgroundColor:y.color.surfaceElevated,borderLeftWidth:3,borderLeftColor:y.color.fillTertiary},groupDescriptionText:{fontSize:11,color:y.color.textSecondary,fontFamily:U,lineHeight:16},routeItem:{marginBottom:6},routeCard:{backgroundColor:y.color.surface,borderRadius:6,borderWidth:1,borderColor:y.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:y.color.text,fontFamily:U,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:y.color.textSecondary,fontFamily:U},typeTag:{borderRadius:4,paddingHorizontal:6,paddingVertical:2,borderWidth:1},typeText:{fontSize:10,fontWeight:"600",fontFamily:U},iconAction:{width:28,height:24,borderRadius:4,backgroundColor:y.color.surfaceElevated,borderWidth:1,borderColor:y.color.border,alignItems:"center",justifyContent:"center"},goButton:{height:24,paddingHorizontal:10,borderRadius:4,alignItems:"center",justifyContent:"center",backgroundColor:y.color.accentSoft,borderWidth:1,borderColor:y.color.accentBorder},goButtonText:{fontSize:12,color:y.color.accent,fontFamily:U,fontWeight:"600"},childrenContainer:{borderLeftWidth:2,borderLeftColor:y.color.border,marginLeft:16,marginRight:8,marginTop:2,marginBottom:8}});import{useState as _t,useMemo as qe,useEffect as Jt}from"react";import{ChevronDown as Ta,ChevronRight as Ra,InlineCopyButton as wa,ProUpgradeModal as Ia,buoyColors as Ze,night as j,useSafeAreaInsets as ka,ToolEmptyState as Ba,monoFont as se}from"@buoy-gg/shared-ui/web";import{useIsPro as Da}from"@buoy-gg/license/web";import{DataViewer as Ea}from"@buoy-gg/shared-ui/web/dataViewer";import{useSyncExternalStore as Pa}from"react";var La=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)}}},Q=new La;var $a=[];function Qt(){let e=Pa(r=>Q.subscribe(r),()=>Q.getStack(),()=>$a),t=e.find(r=>r.isFocused)??null,o=()=>{let r=Q.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 C,jsxs as oe}from"react/jsx-runtime";function qt({style:e,injectedStack:t,onAction:o,onCopyValueChange:r}){let a=Qt(),n=t!=null,i=ka({minBottom:8}),u=n?t:a.stack,c=n?true:a.isLoaded,h=n?null:a.error,I=qe(()=>u.find(f=>f.isFocused)??null,[u]),v=u.length,T=v<=1,$=f=>o?o("navigateToIndex",{index:f}):a.navigateToIndex(f),ae=f=>o?o("popToIndex",{index:f}):a.popToIndex(f),O=()=>o?o("goBack"):a.goBack(),N=()=>o?o("popToTop"):a.popToTop(),[P,D]=_t(null),[ee,k]=_t(false),G=Da();Jt(()=>{ee&&G&&k(false)},[ee,G]);let pe=qe(()=>{let f=u.map(E=>({pathname:E.pathname,name:E.name,params:E.params,isFocused:E.isFocused}));return JSON.stringify(f,null,2)},[u]);Jt(()=>{r?.(pe)},[pe,r]);let R=qe(()=>P!==null&&u[P]?u[P]:I,[P,u,I]),V=qe(()=>P!==null&&u[P]&&!u[P].isFocused,[P,u]);if(!c)return C(l,{style:[m.container,e],children:C(l,{style:m.loadingContainer,children:C(p,{style:m.loadingText,testID:"buoy-routes-stack-loading",children:"Loading navigation stack..."})})});if(h)return C(l,{style:[m.container,e],children:oe(l,{style:m.errorContainer,testID:"buoy-routes-stack-error",children:[C(p,{style:m.errorText,children:"Error loading stack"}),C(p,{style:m.errorDetail,testID:"buoy-routes-stack-error-detail",children:h.message})]})});if(u.length===0)return C(l,{style:[m.container,e],children:C(Ba,{testID:"buoy-routes-stack-empty",otto:"walking",title:"No navigation stack",message:"Navigate to a route to see the stack"})});let K=(f,E,H,ce)=>{if(o){let b=globalThis.window?.confirm;(!b||b(`${f}
|
|
4
|
+
Route: ${b.path}`,[{text:"Cancel",style:"cancel"},{text:w<Pe.length-1?"Next":"Navigate",onPress:ne=>{if(ne&&ne.trim()){let fe={...X,[Le]:ne.trim()};ye(b,w+1,fe)}else _.alert("Invalid Value","Please enter a value for the parameter")}}],"plain-text")},[N]),xe=Ne((b,w)=>{if(a){a(b);return}if(!V&&!w?.bypassPro){ae(true);return}if(b.type==="layout"||b.type==="group"){_.alert("Cannot Navigate",`${b.type==="layout"?"Layouts":"Route groups"} are not navigable routes`);return}if(b.type==="dynamic"||b.type==="catch-all"){if(b.params.length===0){try{N.push(b.path)}catch(X){_.alert("Navigation Error",String(X))}return}ye(b);return}try{N.push(b.path)}catch(X){_.alert("Navigation Error",String(X))}},[N,ye,V,a]),le=Ne(()=>{xe(Sa,{bypassPro:true})},[xe]),f=Ne(()=>{v||(T(true),R(),setTimeout(()=>T(false),400))},[v,R]),E=_e(()=>O?`Updated ${sa(O)}`:"Awaiting route data",[O]),H=_e(()=>K?`Source: ${K}`:"Source: unknown",[K]),ce=_e(()=>i&&G.length>0?[{title:"Search Results",icon:"",routes:G}]:P,[i,G,P]);return ee?L(c,{style:[l.container,e],children:[u&&L(c,{style:l.searchContainer,testID:"buoy-routes-sitemap-search-field",children:[d(Ot,{size:16,color:y.color.textTertiary}),d(Lt,{style:l.searchInput,placeholder:"Search routes...",placeholderTextColor:y.color.placeholder,value:i,onChangeText:n,autoCapitalize:"none",autoCorrect:false,autoFocus:true,testID:"buoy-routes-sitemap-search",accessibilityLabel:"Search routes"}),i.length>0&&d(W,{onPress:()=>n(""),style:l.clearButton,testID:"buoy-routes-sitemap-search-clear",accessibilityRole:"button",accessibilityLabel:"Clear route search",children:d(p,{style:l.clearButtonText,children:"\u2715"})}),d(W,{style:l.closeSearchButton,onPress:()=>{s(false),n("")},testID:"buoy-routes-sitemap-search-done",accessibilityRole:"button",accessibilityLabel:"Done searching routes",children:d(p,{style:l.closeSearchText,children:"Done"})})]}),L(Ue,{testID:"buoy-routes-sitemap-scroll",style:l.scrollView,contentContainerStyle:l.scrollContent,children:[!u&&L(c,{style:l.header,children:[L(c,{style:l.actionsRow,children:[L(c,{style:[l.actionWrapper,Z&&l.actionWrapperDesktop],children:[d(W,{style:[l.iconButton,Z&&l.iconButtonDesktop],onPress:le,accessibilityLabel:"Go to home route",accessibilityRole:"button",testID:"buoy-routes-sitemap-home",children:d(ra,{size:Qe,color:y.color.textSecondary})}),d(p,{style:[l.actionLabel,Z&&l.actionLabelDesktop],children:"Home"})]}),L(c,{style:[l.actionWrapper,Z&&l.actionWrapperDesktop],children:[d(na,{value:z,testID:"buoy-routes-sitemap-copy",size:Z?Qe:14,buttonStyle:Z?l.actionButtonHeaderDesktop:l.actionButtonHeader}),d(p,{style:[l.actionLabel,Z&&l.actionLabelDesktop],children:"Copy"})]}),L(c,{style:[l.actionWrapper,Z&&l.actionWrapperDesktop],children:[d(W,{style:[l.iconButton,Z&&l.iconButtonDesktop,v&&l.refreshButtonDisabled],onPress:f,disabled:v,testID:"buoy-routes-sitemap-refresh",accessibilityRole:"button",accessibilityLabel:"Refresh route tree",children:d(ia,{size:Qe,color:v?y.color.textTertiary:y.color.textSecondary})}),d(p,{style:[l.actionLabel,Z&&l.actionLabelDesktop],children:"Refresh"})]}),L(c,{style:[l.actionWrapper,Z&&l.actionWrapperDesktop],children:[d(W,{style:[l.iconButton,Z&&l.iconButtonDesktop],onPress:()=>s(true),testID:"buoy-routes-sitemap-search-open",accessibilityRole:"button",accessibilityLabel:"Search routes",children:d(Ot,{size:Qe,color:y.color.textSecondary})}),d(p,{style:[l.actionLabel,Z&&l.actionLabelDesktop],children:"Search"})]})]}),L(c,{style:l.statsGrid,children:[d(Ee,{value:D.total,label:"Total",id:"total"}),d(Ee,{value:D.static,label:"Static",id:"static"}),d(Ee,{value:D.dynamic,label:"Dynamic",id:"dynamic"}),d(Ee,{value:D.catchAll,label:"Catch-All",id:"catch-all"}),d(Ee,{value:D.layouts,label:"Layouts",id:"layouts"}),d(Ee,{value:D.groups,label:"Groups",id:"groups"})]})]}),ce.length===0?d(ta,{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(b=>d(Ca,{group:b,isExpanded:i.length>0||m.has(b.title),onToggleExpand:()=>Ce(b.title),onNavigate:xe},b.title)),L(c,{style:l.metaFooter,children:[d(p,{style:l.metaText,testID:"buoy-routes-sitemap-updated",children:E}),d(c,{style:l.sourceBadge,children:d(p,{style:l.sourceText,testID:"buoy-routes-sitemap-source",children:H})})]})]}),d(la,{visible:$,onClose:()=>ae(false),featureName:"Route Navigation"})]}):d(c,{style:[l.container,e],children:d(c,{style:l.loadingContainer,children:d(p,{style:l.loadingText,testID:"buoy-routes-sitemap-loading",children:k?"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 L(c,{style:l.statItem,testID:`buoy-routes-stat-${o}`,accessibilityLabel:`${t}, ${e}`,children:[d(p,{style:l.statValue,testID:`buoy-routes-stat-${o}-value`,children:e}),d(p,{style:l.statLabel,children:t})]})}function Ca({group:e,isExpanded:t,onToggleExpand:o,onNavigate:r}){return L(c,{style:l.groupContainer,children:[L(W,{style:l.groupHeader,onPress:o,activeOpacity:.7,testID:Gt(e.title),accessibilityRole:"button",accessibilityLabel:`${e.title}, ${e.routes.length} routes`,children:[L(c,{style:l.groupHeaderLeft,children:[t?d(Ht,{size:14,color:y.color.textSecondary}):d(Mt,{size:14,color:y.color.textSecondary}),d(p,{style:l.groupTitle,children:e.title})]}),d(c,{style:l.groupBadge,children:d(p,{style:l.groupCount,testID:`${Gt(e.title)}-count`,children:e.routes.length})})]}),e.description&&d(c,{style:l.groupDescription,children:d(p,{style:l.groupDescriptionText,children:e.description})}),t&&d(c,{style:l.routesList,children:e.routes.map((a,i)=>d(Kt,{route:a,onNavigate:r},`${a.path}-${i}`))})]})}function Kt({route:e,depth:t=0,onNavigate:o}){let[r,a]=Be(false),i=e.children.length>0,n=Ta(e.type),u=e.type!=="layout"&&e.type!=="group",s=va(e.path),m=i,I=m?r:true;return d(c,{style:[l.routeItem,{marginLeft:t*12}],testID:s,children:L(c,{style:l.routeCard,children:[L(c,{style:l.routeHeader,children:[m?L(W,{style:l.routeHeaderLeft,onPress:()=>a(!r),activeOpacity:.7,testID:`${s}-toggle`,accessibilityRole:"button",accessibilityLabel:`${e.path}, ${e.type}, ${e.children.length} nested`,children:[d(c,{style:l.expandIndicator,children:r?d(Ht,{size:14,color:y.color.textSecondary}):d(Mt,{size:14,color:y.color.textSecondary})}),d(p,{style:l.routePath,numberOfLines:3,testID:`${s}-path`,children:e.path})]}):L(c,{style:l.routeHeaderLeft,accessible:true,accessibilityLabel:`${e.path}, ${e.type}`,children:[d(c,{style:l.expandIndicator}),d(p,{style:l.routePath,numberOfLines:3,testID:`${s}-path`,children:e.path})]}),L(c,{style:l.routeHeaderActions,children:[i&&d(c,{style:l.childCountBadge,children:d(p,{style:l.childCountText,testID:`${s}-children-count`,children:e.children.length})}),d(c,{style:[l.typeTag,{backgroundColor:`${n}15`,borderColor:`${n}40`}],children:d(p,{style:[l.typeText,{color:n}],testID:`${s}-type`,children:e.type.toUpperCase()})}),d(aa,{value:e.path,buttonStyle:l.iconAction,testID:`${s}-copy`}),u&&d(W,{style:l.goButton,onPress:()=>o(e),activeOpacity:.7,testID:`${s}-go`,accessibilityRole:"button",accessibilityLabel:`Go to ${e.path}`,children:d(p,{style:l.goButtonText,children:"Go"})})]})]}),I&&i&&d(c,{style:l.childrenContainer,children:e.children.map((v,T)=>d(Kt,{route:v,depth:t+1,onNavigate:o},`${v.path}-${T}`))})]})})}function Ta(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 l=ve.create({container:{flex:1,backgroundColor:"transparent"},loadingContainer:{flex:1,justifyContent:"center",alignItems:"center"},loadingText:{color:y.color.textSecondary,fontSize:14,fontFamily:U,textAlign:"center",lineHeight:20,paddingHorizontal:32,maxWidth:420},header:{flexDirection:"column",padding:8,borderBottomWidth:1,borderBottomColor:y.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:y.color.surface,borderRadius:8,paddingVertical:10,paddingHorizontal:12,alignItems:"center"},statValue:{fontSize:18,fontWeight:"800",color:y.color.text,fontFamily:U},statLabel:{fontSize:10,color:y.color.textTertiary,marginTop:4,fontFamily:U,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:y.color.surfaceElevated},actionButtonHeaderDesktop:{padding:12,borderRadius:8,backgroundColor:y.color.surfaceElevated},iconButton:{padding:6,borderRadius:4,alignItems:"center",justifyContent:"center"},iconButtonDesktop:{padding:12,borderRadius:8,backgroundColor:y.color.surfaceElevated},actionLabel:{fontSize:8,color:y.color.textTertiary,fontFamily:U,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:y.color.border},metaText:{fontSize:12,color:y.color.textSecondary,fontFamily:U},sourceBadge:{paddingHorizontal:8,paddingVertical:2,borderRadius:999,borderWidth:1,borderColor:y.color.border,backgroundColor:y.color.surface},sourceText:{fontSize:11,color:y.color.textSecondary,textTransform:"capitalize",fontFamily:U},searchContainer:{flexDirection:"row",alignItems:"center",padding:8,gap:8,borderBottomWidth:1,borderBottomColor:y.color.border},searchInput:{flex:1,color:y.color.text,fontSize:14,fontFamily:U},clearButton:{padding:4},clearButtonText:{color:y.color.textTertiary,fontSize:18},closeSearchButton:{paddingHorizontal:8,paddingVertical:4},closeSearchText:{color:y.color.accent,fontSize:14,fontWeight:"600",fontFamily:U},scrollView:{flex:1},scrollContent:{paddingBottom:8},emptyState:{padding:32,alignItems:"center"},emptyText:{color:y.color.textSecondary,fontSize:14,fontFamily:U},groupContainer:{marginVertical:4},groupHeader:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",padding:12,paddingHorizontal:16,backgroundColor:y.color.surface,borderLeftWidth:3,borderLeftColor:y.color.fillTertiary},groupHeaderLeft:{flexDirection:"row",alignItems:"center",gap:8,flex:1},groupTitle:{fontSize:12,fontWeight:"700",color:y.color.text,fontFamily:U,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:U},routesList:{backgroundColor:"transparent"},groupDescription:{paddingHorizontal:16,paddingVertical:8,marginBottom:8,backgroundColor:y.color.surfaceElevated,borderLeftWidth:3,borderLeftColor:y.color.fillTertiary},groupDescriptionText:{fontSize:11,color:y.color.textSecondary,fontFamily:U,lineHeight:16},routeItem:{marginBottom:6},routeCard:{backgroundColor:y.color.surface,borderRadius:6,borderWidth:1,borderColor:y.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:y.color.text,fontFamily:U,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:y.color.textSecondary,fontFamily:U},typeTag:{borderRadius:4,paddingHorizontal:6,paddingVertical:2,borderWidth:1},typeText:{fontSize:10,fontWeight:"600",fontFamily:U},iconAction:{width:28,height:24,borderRadius:4,backgroundColor:y.color.surfaceElevated,borderWidth:1,borderColor:y.color.border,alignItems:"center",justifyContent:"center"},goButton:{height:24,paddingHorizontal:10,borderRadius:4,alignItems:"center",justifyContent:"center",backgroundColor:y.color.accentSoft,borderWidth:1,borderColor:y.color.accentBorder},goButtonText:{fontSize:12,color:y.color.accent,fontFamily:U,fontWeight:"600"},childrenContainer:{borderLeftWidth:2,borderLeftColor:y.color.border,marginLeft:16,marginRight:8,marginTop:2,marginBottom:8}});import{useState as _t,useMemo as qe,useEffect as Jt}from"react";import{ChevronDown as Ra,ChevronRight as wa,InlineCopyButton as Ia,ProUpgradeModal as ka,buoyColors as Ze,night as j,useSafeAreaInsets as Ba,ToolEmptyState as Da,monoFont as se}from"@buoy-gg/shared-ui/web";import{useIsPro as Ea}from"@buoy-gg/license/web";import{DataViewer as Pa}from"@buoy-gg/shared-ui/web/dataViewer";import{useSyncExternalStore as La}from"react";var $a=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)}}},Q=new $a;var Fa=[];function Qt(){let e=La(r=>Q.subscribe(r),()=>Q.getStack(),()=>Fa),t=e.find(r=>r.isFocused)??null,o=()=>{let r=Q.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 C,jsxs as oe}from"react/jsx-runtime";function qt({style:e,injectedStack:t,onAction:o,onCopyValueChange:r}){let a=Qt(),i=t!=null,n=Ba({minBottom:8}),u=i?t:a.stack,s=i?true:a.isLoaded,m=i?null:a.error,I=qe(()=>u.find(f=>f.isFocused)??null,[u]),v=u.length,T=v<=1,$=f=>o?o("navigateToIndex",{index:f}):a.navigateToIndex(f),ae=f=>o?o("popToIndex",{index:f}):a.popToIndex(f),V=()=>o?o("goBack"):a.goBack(),N=()=>o?o("popToTop"):a.popToTop(),[P,D]=_t(null),[ee,k]=_t(false),G=Ea();Jt(()=>{ee&&G&&k(false)},[ee,G]);let pe=qe(()=>{let f=u.map(E=>({pathname:E.pathname,name:E.name,params:E.params,isFocused:E.isFocused}));return JSON.stringify(f,null,2)},[u]);Jt(()=>{r?.(pe)},[pe,r]);let R=qe(()=>P!==null&&u[P]?u[P]:I,[P,u,I]),O=qe(()=>P!==null&&u[P]&&!u[P].isFocused,[P,u]);if(!s)return C(c,{style:[h.container,e],children:C(c,{style:h.loadingContainer,children:C(p,{style:h.loadingText,testID:"buoy-routes-stack-loading",children:"Loading navigation stack..."})})});if(m)return C(c,{style:[h.container,e],children:oe(c,{style:h.errorContainer,testID:"buoy-routes-stack-error",children:[C(p,{style:h.errorText,children:"Error loading stack"}),C(p,{style:h.errorDetail,testID:"buoy-routes-stack-error-detail",children:m.message})]})});if(u.length===0)return C(c,{style:[h.container,e],children:C(Da,{testID:"buoy-routes-stack-empty",otto:"walking",title:"No navigation stack",message:"Navigate to a route to see the stack"})});let K=(f,E,H,ce)=>{if(o){let b=globalThis.window?.confirm;(!b||b(`${f}
|
|
5
5
|
|
|
6
|
-
${E}`))&&ce();return}_.alert(f,E,[{text:"Cancel",style:"cancel"},{text:H,style:"destructive",onPress:ce}])},z=()=>{if(!G){k(true);return}if(T){_.alert("Cannot Go Back","Already at the root of the stack");return}O()},Ce=()=>{if(!G){k(true);return}if(T){_.alert("Already at Top","Stack only has one screen");return}K("Pop to Top","This will remove all screens except the root screen.","Pop to Top",N)},ye=f=>{D(P===f?null:f)},xe=()=>{if(!G){k(true);return}if(R){if(R.isFocused){_.alert("Already There","This route is already visible");return}$(R.index)}},le=()=>{if(!G){k(true);return}if(!R)return;if(R.isFocused){_.alert("Cannot Pop","Selected route is already visible");return}if(R.index===v-1){_.alert("Cannot Pop","No screens above selected route");return}let f=v-1-R.index,E=R.index;K("Pop to Route",`Remove ${f} screen${f!==1?"s":""} above ${R.pathname}?`,"Pop",()=>ae(E))};return oe(l,{style:[m.container,e],children:[C(Ue,{testID:"buoy-routes-stack-scroll",style:m.stackScroll,contentContainerStyle:[m.stackContent,{paddingBottom:m.stackContent.padding+i.bottom}],children:[...u].reverse().map((f,E)=>{let H=u.length-1-E,ce=P===H,b=Object.keys(f.params).length>0,w=va(H);return C(l,{style:m.stackItemWrapper,testID:w,children:oe(l,{style:[m.stackItem,ce&&m.stackItemSelected],children:[oe(W,{style:m.stackItemHeader,onPress:()=>ye(H),activeOpacity:.7,testID:`${w}-toggle`,accessibilityRole:"button",accessibilityLabel:`${f.pathname}, ${f.isFocused?"focused":"mounted"}, position ${H} of ${v-1}`,children:[C(l,{style:m.expandIndicator,children:ce?C(Ta,{size:14,color:j.color.textSecondary}):C(Ra,{size:14,color:j.color.textSecondary})}),C(p,{style:m.stackItemPath,numberOfLines:1,testID:`${w}-path`,children:f.pathname}),C(wa,{value:f.pathname,buttonStyle:m.copyRouteButton,testID:`${w}-copy`}),C(l,{style:[m.statusBadge,{backgroundColor:f.isFocused?`${Ze.success}15`:"#3B82F615",borderColor:f.isFocused?`${Ze.success}40`:"#3B82F640"}],children:C(p,{style:[m.statusBadgeText,{color:f.isFocused?Ze.success:"#3B82F6"}],testID:`${w}-status`,children:f.isFocused?"FOCUSED":"MOUNTED"})})]}),ce&&oe(l,{style:m.expandedContent,children:[oe(l,{style:m.detailRow,children:[C(p,{style:m.detailLabel,children:"Route Name:"}),C(p,{style:m.detailValue,testID:`${w}-name`,children:f.name})]}),oe(l,{style:m.detailRow,children:[C(p,{style:m.detailLabel,children:"Position:"}),oe(p,{style:m.detailValue,testID:`${w}-position`,children:[H," / ",v-1]})]}),b&&C(l,{style:m.dataViewerContainer,children:C(Ea,{title:"Parameters",data:f.params,showTypeFilter:false})}),oe(l,{style:m.actionsRow,children:[oe(l,{style:m.actionWrapper,children:[C(W,{style:[m.actionButton,T&&m.actionButtonDisabled],onPress:z,disabled:T,testID:`${w}-back`,accessibilityRole:"button",accessibilityLabel:"Go back one screen",children:C(p,{style:[m.actionButtonText,T&&m.actionButtonTextDisabled],children:"Back"})}),C(p,{style:m.helpText,children:"Go back one screen"})]}),oe(l,{style:m.actionWrapper,children:[C(W,{style:[m.actionButton,f.isFocused&&m.actionButtonDisabled],onPress:xe,disabled:f.isFocused,testID:`${w}-go`,accessibilityRole:"button",accessibilityLabel:`Navigate to ${f.pathname}`,children:C(p,{style:[m.actionButtonText,f.isFocused&&m.actionButtonTextDisabled],children:"Go"})}),C(p,{style:m.helpText,children:"Navigate to this route"})]}),oe(l,{style:m.actionWrapper,children:[C(W,{style:[m.actionButton,(f.isFocused||H===v-1)&&m.actionButtonDisabled],onPress:le,disabled:f.isFocused||H===v-1,testID:`${w}-pop-to`,accessibilityRole:"button",accessibilityLabel:`Remove screens above ${f.pathname}`,children:C(p,{style:[m.actionButtonText,(f.isFocused||H===v-1)&&m.actionButtonTextDisabled],children:"Pop To"})}),C(p,{style:m.helpText,children:"Remove screens above this"})]})]})]})]})},`stack-${H}-${f.key}`)})}),C(Ia,{visible:ee,onClose:()=>k(false),featureName:"Stack Navigation"})]})}var m=ve.create({container:{flex:1,backgroundColor:"transparent"},loadingContainer:{flex:1,justifyContent:"center",alignItems:"center",padding:32},loadingText:{color:j.color.textSecondary,fontSize:14,fontFamily:se},errorContainer:{flex:1,justifyContent:"center",alignItems:"center",padding:32},errorText:{color:Ze.error,fontSize:16,fontWeight:"600",fontFamily:se,marginBottom:8},errorDetail:{color:j.color.textSecondary,fontSize:12,fontFamily:se,textAlign:"center"},emptyContainer:{flex:1,justifyContent:"center",alignItems:"center",padding:32},emptyText:{color:j.color.text,fontSize:16,fontWeight:"600",fontFamily:se,marginBottom:8},emptySubtext:{color:j.color.textSecondary,fontSize:14,fontFamily:se,textAlign:"center"},stackScroll:{flex:1},stackContent:{padding:8},stackItemWrapper:{marginBottom:6},stackItem:{backgroundColor:j.color.surface,borderRadius:6,borderWidth:1,borderColor:j.color.border,overflow:"hidden"},stackItemSelected:{borderColor:j.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:j.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:j.color.border},detailRow:{marginBottom:8},detailLabel:{fontSize:10,color:j.color.textSecondary,fontFamily:se,marginBottom:2},detailValue:{fontSize:12,color:j.color.text,fontFamily:se},dataViewerContainer:{marginTop:4,marginHorizontal:-12,marginBottom:8},actionsRow:{flexDirection:"row",gap:6,marginTop:12},actionWrapper:{flex:1},actionButton:{backgroundColor:j.color.surfaceElevated,paddingVertical:8,paddingHorizontal:8,borderRadius:6,alignItems:"center"},actionButtonDisabled:{opacity:.5},actionButtonText:{fontSize:12,fontWeight:"600",color:j.color.text,fontFamily:se},actionButtonTextDisabled:{color:j.color.textTertiary},helpText:{fontSize:9,color:j.color.textSecondary,fontFamily:se,textAlign:"center",marginTop:4,lineHeight:12}});import{useCallback as Fa}from"react";import{Navigation as za,night as gt,EVENT_LIST_PRESET as Aa,monoFont as Zt}from"@buoy-gg/shared-ui/web";import{memo as Na,useMemo as de}from"react";import{CompactRow as Wa,RelativeTime as ja,buoyColors as Xt,night as Xe,monoFont as Yt}from"@buoy-gg/shared-ui/web";import{jsx as je}from"react/jsx-runtime";function Oa(e){return e.pathname==="/"?"home":ct(e.pathname,e.segments)?"dynamic":e.params&&Object.keys(e.params).length>0?"with-params":"default"}function Va(e){switch(e){case"home":return Xt.success;case"dynamic":return Xe.color.accent;case"with-params":return Xt.warning;default:return Xe.color.textSecondary}}function Ha(e){switch(e){case"home":return"Home";case"dynamic":return"Dynamic";case"with-params":return"Params";default:return"Static"}}function Ma(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 Ua(e){let t=[];e.timeSincePrevious!==void 0&&e.timeSincePrevious>0&&t.push(Ma(e.timeSincePrevious));let o=e.segments?.length||0;return o>0&&t.push(`depth ${o}`),t.join(" \xB7 ")||"root"}function Ga(e){if(e.params&&Object.keys(e.params).length>0){let t=Object.keys(e.params).length;return`${t} PARAM${t!==1?"S":""}`}}var eo=Na(function({event:e,visitNumber:t,isExpanded:o,onPress:r,onNavigate:a,index:n}){let i=de(()=>Oa(e),[e]),u=de(()=>ct(e.pathname,e.segments),[e.pathname,e.segments]),c=de(()=>Va(i),[i]),h=de(()=>Ha(i),[i]),I=de(()=>Ua(e),[e]),v=de(()=>Ga(e),[e]),T=de(()=>fa(e.pathname,t),[e.pathname,t]),$=de(()=>`${e.pathname}, ${h}, ${I}`,[e.pathname,h,I]),ae=de(()=>{if(o)return je(lt,{event:e,visitNumber:t,routeTemplate:u})},[o,e,t,u]),O=de(()=>{if(a)return je(W,{style:to.goButton,onPress:()=>a(Nt(e.pathname,e.params)),testID:`${T}-go`,accessibilityRole:"button",accessibilityLabel:`Go to ${e.pathname}`,children:je(p,{style:to.goButtonText,children:"Go"})})},[a,e.pathname,T]);return je(Wa,{statusDotColor:c,statusLabel:h,statusSublabel:I,primaryText:e.pathname,badgeText:v,badgeColor:c,trailingAction:O,bottomRightText:je(ja,{timestamp:e.timestamp}),showChevron:true,expandedContent:ae,isExpanded:o,expandedGlowColor:c,onPress:()=>r(n),testID:T,statusTestID:`${T}-status`,statusSublabelTestID:`${T}-sublabel`,accessibilityLabel:$})}),to=ve.create({badgeText:{fontSize:11,fontWeight:"600",fontFamily:Yt},goButton:{backgroundColor:Xe.color.accent,paddingHorizontal:8,paddingVertical:4,borderRadius:4},goButtonText:{fontSize:10,fontWeight:"600",color:Xe.color.onAccent,fontFamily:Yt}});import{jsx as Oe,jsxs as Ka}from"react/jsx-runtime";function _a({events:e,visitCounts:t,onNavigate:o,onSelectEvent:r}){let a=Fa(n=>{let i=e[n];i&&r(i,t.get(i)||1)},[e,t,r]);return e.length===0?Ka(l,{style:Ye.emptyState,testID:"buoy-routes-empty",children:[Oe(za,{size:48,color:gt.color.textTertiary}),Oe(p,{style:Ye.emptyTitle,testID:"buoy-routes-empty-title",children:"No events yet"}),Oe(p,{style:Ye.emptySubtitle,testID:"buoy-routes-empty-subtitle",children:"Navigation events will appear here"})]}):Oe(Pt,{testID:"buoy-routes-timeline",contentContainerStyle:Ye.listContent,data:e,keyExtractor:n=>`${n.timestamp}-${n.pathname}`,renderItem:({item:n,index:i})=>Oe(eo,{event:n,visitNumber:t.get(n)||1,isExpanded:false,index:i,onPress:a,onNavigate:o}),showsVerticalScrollIndicator:true,...Aa})}var Ye=ve.create({listContent:{paddingVertical:8},emptyState:{flex:1,justifyContent:"center",alignItems:"center",padding:32},emptyTitle:{color:gt.color.text,fontSize:16,fontWeight:"600",marginTop:16,marginBottom:8,fontFamily:Zt,letterSpacing:.5,textTransform:"uppercase"},emptySubtitle:{color:gt.color.textSecondary,fontSize:14,textAlign:"center",fontFamily:Zt}});import{Fragment as Ja,jsx as S,jsxs as re}from"react/jsx-runtime";var yt=Tr(),Qa={parse:e=>e==="routes"||e==="events"||e==="stack"?e:void 0,serialize:e=>e},qa={parse:e=>e==="true",serialize:e=>e.toString()},Za={parse:e=>new Set(JSON.parse(e)),serialize:e=>JSON.stringify(Array.from(e))};function oo(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=oo(o.state,t);if(r)return[o.name,...r]}}return null}function Xa(e,t){if(e.length===0)return null;let o=t&&Object.keys(t).length>0?t:void 0;if(e.length===1)return yt.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 yt.navigate({name:e[0],params:r})}function ft({visible:e,onClose:t,onBack:o,onMinimize:r,enableSharedModalDimensions:a=false,inline:n=false,remote:i}){let u=Rr(),c=void 0,h=wr(),[I,v]=at($e.routeEvents.activeTab(),"events",Qa),[T,$]=we(false),[ae,O]=we(""),N=jr(),P=Wr("routeEvents.entries");Bt(()=>{T&&N&&$(false)},[T,N]);let[D,ee]=at($e.routeEvents.isMonitoring(),true,qa),{events:k,clearEvents:G,isListening:pe}=At({enabled:D}),R=D&&pe;Bt(()=>{he.setBootCapture(D)},[D]);let[V,K]=we(false),[z,Ce]=we(null),[ye,xe]=we(1),[le,f]=we(""),[E,H]=at($e.routeEvents.eventFilters(),new Set(["/_sitemap","/api","/__dev"]),Za),ce=Ro(null),b=ue(g=>{},[]),w=ue(g=>{try{if(i){if(!i.onNavigatePath)return;if(!N&&g!=="/"){$(true);return}i.onNavigatePath(g);return}if(h)u.push(g);else if(c){let{pathname:B,params:q}=Qr(g),me=B.startsWith("/")?B.slice(1):B,Te=Object.keys(q).length>0,Re=c.getRootState?.();if(Re){let Me=oo(Re,me);if(Me){let wt=Xa(Me,q);if(wt){c.dispatch(wt);return}}}c.dispatch(yt.navigate(Te?{name:me,params:q}:{name:me}))}else _.alert("Navigation Unavailable","No Expo Router or React Navigation container was found in this app.")}catch(B){_.alert("Navigation Error",String(B))}},[u,c,h,i,N]),X=ue(()=>{ee(g=>!g)},[]),Pe=ue(()=>{if(k.length!==0){if(!N){$(true);return}G()}},[k.length,N,G]),Le=ue(g=>{H(B=>{let q=new Set(B);return q.has(g)?q.delete(g):q.add(g),q})},[]),et=ue(g=>{H(B=>new Set([...B,g]))},[]),ne=ue(()=>{K(!V)},[V]),fe=ue((g,B)=>{Ce(g),xe(B)},[]),He=ue(()=>{Ce(null)},[]),po=ue(g=>{Ce(null),v(g)},[]),mo=Ie(()=>{let g=new Set;return k.forEach(B=>{B.pathname&&g.add(B.pathname)}),Array.from(g).sort()},[k]),be=Ie(()=>k.filter(g=>{if(!g.pathname||Array.from(E).some(B=>g.pathname.includes(B)))return false;if(le.trim()){let B=le.toLowerCase(),q=g.pathname.toLowerCase().includes(B),me=Object.entries(g.params||{}).some(([Te,Re])=>{let Me=Array.isArray(Re)?Re.join(" "):Re;return Te.toLowerCase().includes(B)||Me.toLowerCase().includes(B)});return q||me}return true}),[k,E,le]),ho=Ie(()=>be.slice(0,P),[be,P]),tt=Ie(()=>Math.max(0,be.length-P),[be.length,P]),ot=Ie(()=>{let g=new Map,B=new Map;for(let q=k.length-1;q>=0;q--){let me=k[q],Te=(g.get(me.pathname)||0)+1;g.set(me.pathname,Te),B.set(me,Te)}return B},[k]),go=Ie(()=>({summary:{total:k.length,filtered:be.length,listening:R,ignoredPatterns:Array.from(E),timestamp:new Date().toISOString()},events:be.map((g,B)=>({index:B,visitNumber:ot.get(g)||1,pathname:g.pathname,timestamp:g.timestamp,timestampRelative:Pr(g.timestamp),params:g.params,segments:g.segments,previousPathname:g.previousPathname,timeSincePrevious:g.timeSincePrevious}))}),[k.length,be,R,E,ot]);if(!e)return null;let yo=a?$e.modal.root():$e.routeEvents.modal(),rt=null,Ct=()=>{if(z)return S(jt,{event:z,visitNumber:ye,onNavigate:w});if(I==="routes")return h||i?.sitemap?S(ht,{style:A.contentWrapper,injectedRoutes:i?.sitemap?.routes,injectedSource:i?.sitemap?.source??null,injectedLastUpdatedAt:i?.sitemap?.lastUpdatedAt??null,onNavigateRoute:i?fo:void 0}):S(ht,{style:A.contentWrapper});if(I==="stack")return S(qt,{style:A.contentWrapper,injectedStack:i?i.stack??[]:void 0,onAction:i?.onStackAction,onCopyValueChange:O});if(V)return S(Xr,{ignoredPatterns:E,onTogglePattern:Le,onAddPattern:et,availablePathnames:mo});let g=k.length>0;return be.length===0?re(l,{style:A.contentWrapper,testID:"buoy-routes-events",children:[g&&S(l,{style:A.searchContainer,testID:"buoy-routes-search-field",children:S($t,{value:le,onChange:f,placeholder:"Search pathname or params...",testID:"buoy-routes-search"})}),S(kr,{testID:"buoy-routes-empty",...Br({subject:"route events",search:le,total:k.length,capturing:R,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"}})})]}):re(l,{style:A.contentWrapper,testID:"buoy-routes-events",children:[S(l,{style:A.searchContainer,testID:"buoy-routes-search-field",children:S($t,{value:le,onChange:f,placeholder:"Search pathname or params...",testID:"buoy-routes-search"})}),tt>0&&re(l,{style:A.lockedEventsBanner,testID:"buoy-routes-locked-banner",children:[S(Fr,{size:14,color:M.color.warning}),re(p,{style:A.lockedEventsBannerText,testID:"buoy-routes-locked-banner-text",children:[tt," older ",tt===1?"event":"events"," locked"]}),S(p,{style:A.lockedEventsBannerSubtext,children:"Upgrade to Pro for full history"})]}),S(_a,{events:ho,visitCounts:ot,onNavigate:w,onSelectEvent:fe})]})},Tt=z?re(ie,{children:[S(ie.Navigation,{onBack:He}),S(ie.Content,{title:z.pathname,testID:"buoy-routes-detail-title"}),S(ie.Actions,{children:S(nt,{testID:"buoy-routes-detail-copy",value:{pathname:z.pathname,previousPathname:z.previousPathname,params:z.params,segments:z.segments,timestamp:z.timestamp,timestampISO:new Date(z.timestamp).toISOString(),timeSincePrevious:z.timeSincePrevious,visitNumber:ye},buttonStyle:A.iconButton})})]}):V?re(ie,{children:[S(ie.Navigation,{onBack:()=>K(false)}),S(ie.Content,{title:"Filters",testID:"buoy-routes-filters-title"})]}):re(ie,{children:[o&&S(ie.Navigation,{onBack:o}),S(ie.Content,{title:"",noMargin:true,children:S(Er,{tabs:[{key:"routes",label:h?"Routes":"Screens"},{key:"events",label:`Events${k.length>0&&I!=="events"?` (${k.length})`:""}`},{key:"stack",label:"Stack"}],activeTab:I,onTabChange:g=>po(g),testIDPrefix:"buoy-routes-tab"})}),re(ie.Actions,{children:[I==="stack"&&S(nt,{value:ae,buttonStyle:A.iconButton,testID:"buoy-routes-stack-copy"}),I==="events"&&re(Ja,{children:[S(nt,{value:go,buttonStyle:A.iconButton,testID:"buoy-routes-copy"}),S(W,{onPress:ne,style:[A.iconButton,E.size>0&&A.activeFilterButton],testID:"buoy-routes-filters",accessibilityRole:"button",accessibilityLabel:E.size>0?`Route filters, ${E.size} active`:"Route filters",children:S($r,{size:14,color:E.size>0?M.color.accent:M.color.textSecondary})}),S(Ar,{isEnabled:R,onToggle:X,accessibilityLabel:"Toggle route event monitoring",testID:"buoy-routes-power"}),S(W,{onPress:Pe,style:A.iconButton,testID:"buoy-routes-clear",accessibilityRole:"button",accessibilityLabel:"Clear route events",children:S(Lr,{size:14,color:M.color.danger})})]})]})]}),fo=g=>{if(g.type==="layout"||g.type==="group")return;let B=g.type==="index"||g.path==="/";if(!N&&!B){$(true);return}i?.onNavigateRoute?.(g)},Rt=S(zr,{visible:T,onClose:()=>$(false),featureName:"Route Event Management"});return n?re(Ft,{children:[re(l,{style:A.inlineRoot,children:[S(l,{style:A.inlineHeader,...Ir,children:Tt}),Ct(),rt]}),Rt]}):S(Ft,{children:re(Dr,{visible:e,onClose:t,onMinimize:r,persistenceKey:yo,header:{showToggleButton:true,customContent:Tt},onModeChange:b,enablePersistence:true,initialMode:"bottomSheet",enableGlitchEffects:true,disableScrollWrapper:true,styles:{},footer:rt,footerHeight:rt?68:0,children:[Ct(),Rt]})})}function Ya(e={}){return S(ft,{...e,inline:true,visible:true,onClose:()=>{}})}var A=ve.create({inlineRoot:{flex:1,minHeight:0,backgroundColor:"transparent"},inlineHeader:{paddingHorizontal:12,paddingVertical:8,borderBottomWidth:1,borderBottomColor:Nr.border,backgroundColor:"transparent"},iconButton:{padding:6,borderRadius:6,backgroundColor:M.color.buttonSurface},activeFilterButton:{backgroundColor:M.color.accentSoft},emptyState:{flex:1,justifyContent:"center",alignItems:"center",padding:32},emptyTitle:{color:M.color.text,fontSize:16,fontWeight:"600",marginTop:16,marginBottom:8,fontFamily:Ge,letterSpacing:.5,textTransform:"uppercase"},emptySubtitle:{color:M.color.textSecondary,fontSize:14,textAlign:"center",fontFamily:Ge},contentWrapper:{flex:1},statsContainer:{paddingHorizontal:16,paddingVertical:8,backgroundColor:M.color.surface,borderBottomWidth:1,borderBottomColor:M.color.border},statsText:{fontSize:11,color:M.color.textSecondary,fontFamily:Ge,textAlign:"center"},statsWarning:{color:M.color.warning,fontWeight:"600"},searchContainer:{paddingHorizontal:16,paddingVertical:8,backgroundColor:"transparent"},lockedEventsBanner:{flexDirection:"row",alignItems:"center",gap:8,backgroundColor:M.color.warningSoft,borderWidth:1,borderColor:M.color.warning+"30",borderRadius:8,paddingVertical:10,paddingHorizontal:14,marginHorizontal:16,marginBottom:8},lockedEventsBannerText:{fontSize:12,fontWeight:"600",color:M.color.warning,fontFamily:Ge},lockedEventsBannerSubtext:{fontSize:11,color:M.color.textSecondary,marginLeft:"auto"}});import{createToolFactory as en,defineToolPreset as tn}from"@buoy-gg/shared-ui/web";import{jsx as on}from"react/jsx-runtime";var ro=tn({id:"route-events",name:"ROUTES",description:"Route tracking & navigation inspector",slot:"both",icon:({size:e})=>on(To,{size:e}),component:ft,props:{enableSharedModalDimensions:false}}),rn=en(ro,e=>({enableSharedModalDimensions:e.enableSharedModalDimensions??false}));import{useEffect as an}from"react";import{browserRouter as ao,getBrowserHref as nn,getBrowserRouteURL as no,subscribeBrowserNavigation as sn}from"@buoy-gg/shared-ui/web/utils";var io=0,bt;function ln(){if(typeof window>"u")return()=>{};if(io++===0){he.hydrateBootCapture();let t,o,r="",a=[],n=-1,i=c=>{if(c.href===r&&c.kind==="pop")return;if(c.kind==="replace"&&n>=0)a[n]=c.href;else if(c.kind==="pop"){let v=a.lastIndexOf(c.href,n-1),T=a.indexOf(c.href,n+1);v>=0?n=v:T>=0?n=T:(a.splice(n+1),a.push(c.href),n++)}else a.splice(n+1),a.push(c.href),n++;r=c.href;let h=no(c.href),I=Date.now();Fe.emit({pathname:h.pathname,params:Object.fromEntries(h.searchParams),segments:h.pathname.split("/").filter(Boolean),previousPathname:t,timestamp:I,timeSincePrevious:o===void 0?void 0:I-o}),t=h.pathname,o=I,Q.setStack(a.map((v,T)=>{let $=no(v);return{key:`browser:${T}`,name:$.pathname,pathname:$.pathname,params:Object.fromEntries($.searchParams),index:T,isFocused:T===n,canPop:T>0}}))},u=c=>{if(!Number.isInteger(c)||c<0||c>=a.length)throw new Error("That browser history entry is unavailable.");window.history.go(c-n)};Q.setActions({navigateToIndex:u,popToIndex:u,goBack:ao.back,popToTop:()=>u(0),navigateToRoute:(c,h)=>(ao.push({pathname:c,params:h}),true)}),bt=sn(i),i({href:nn(),kind:"initial"})}let e=false;return()=>{e||(e=true,--io===0&&(bt?.(),bt=void 0,Q.setActions(null)))}}function cn(){return an(ln,[]),null}import{useEffect as so,useRef as vt}from"react";import{useSafePathname as un,useSafeSegments as dn,useSafeGlobalSearchParams as pn}from"@buoy-gg/shared-ui/web";function mn(e){let t=un(),o=dn(),r=pn(),a=vt(e),n=vt(void 0),i=vt(void 0);so(()=>{a.current=e},[e]),so(()=>{let u=Date.now(),c=i.current?u-i.current:void 0,h={pathname:t,params:r,segments:o,timestamp:u,previousPathname:n.current,timeSincePrevious:c};n.current=t,i.current=u,Fe.emit(h),a.current&&a.current(h)},[t,o,r])}import{useEffect as lo,useRef as xt}from"react";function co(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=co(t.state);if(r.route)return{route:r.route,segments:[...o,...r.segments]}}return{route:t,segments:o}}function uo(e,t,o,r){if(!e)return;let{route:a,segments:n}=co(e);if(!a)return;let i=`/${a.name}`;if(i===t.current)return;let u=Date.now(),c=o.current?u-o.current:void 0,h={pathname:i,params:a.params||{},segments:n,timestamp:u,previousPathname:t.current,timeSincePrevious:c};t.current=i,o.current=u,Fe.emit(h),r.current&&r.current(h)}function hn(e){let t=void 0,o=xt(e),r=xt(void 0),a=xt(void 0);lo(()=>{o.current=e},[e]),lo(()=>{if(!t)return;let n=t.getRootState?.();n&&uo(n,r,a,o);let i=t.addListener?.("state",()=>{let u=t.getRootState?.();uo(u,r,a,o)});return()=>{i?.()}},[t])}import{getSafeRouter as gn}from"@buoy-gg/shared-ui/web";import{isOverWireBudget as yn}from"@buoy-gg/shared-ui/web";var fn=16*1024,bn=Object.freeze({__buoyOmitted:"route-params",note:"Navigation params stay on the device."});function St(e){return e==null?false:yn(e,fn)}function Ve(e){return St(e)?bn:e}function vn(e){return St(e.params)?{...e,params:Ve(e.params)}:e}function xn(e){return St(e.params)?{...e,params:Ve(e.params)}:e}function Sn(){let e=pt();return{routes:ge.parseRouteTree(We()),source:e.source,lastUpdatedAt:e.lastLoadedAt}}var Cn={version:3,getSnapshot:()=>({events:he.getEvents().map(vn),sitemap:Sn(),stack:Q.getStack().map(xn)}),subscribe:e=>{let t=he.subscribeToEvents(e),o=Q.subscribe(e),r=null;if(!We()){let a=0,n=100,i=()=>{if(a+=1,We()){r=null,e();return}r=a<n?setTimeout(i,100):null};r=setTimeout(i,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:Ve(e.params),at:e.timestamp,source:"event"};let t=Q.getStack(),o=t.find(r=>r.isFocused)??t[t.length-1];return o?.pathname?{path:o.pathname,params:Ve(o.params??{}),at:null,source:"stack"}:e?{path:e.pathname,params:Ve(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=gn();if(!r){let a=Q.getActions(),n=o.replace(/^\//,"");if(!a?.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(!a.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"}}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=Q.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=Q.getActions();if(!o)throw new Error("navigation stack is not available");return o.popToIndex(t),{poppedToIndex:t}},stackGoBack:()=>{let e=Q.getActions();if(!e)throw new Error("navigation stack is not available");return e.goBack(),{wentBack:true}},stackPopToTop:()=>{let e=Q.getActions();if(!e)throw new Error("navigation stack is not available");return e.popToTop(),{poppedToTop:true}}}};export{qt as NavigationStack,jt as RouteEventDetail,lt as RouteEventExpandedContent,eo as RouteEventItemCompact,ft as RouteEventsModalWithTabs,zt as RouteObserver,ge as RouteParser,cn as RouteTracker,ht as RoutesSitemap,Ya as RoutesToolView,rn as createRouteEventsTool,Q as navigationStackStore,pa as registerBrowserRoutes,he as routeEventStore,Cn as routeEventsSyncAdapter,ro as routeEventsToolPreset,Fe as routeObserver,Qt as useNavigationStack,ya as useParentRoutes,ga as useRoute,At as useRouteEvents,mn as useRouteObserver,hn as useRouteObserverReactNavigation,Je as useRouteSitemap};
|
|
6
|
+
${E}`))&&ce();return}_.alert(f,E,[{text:"Cancel",style:"cancel"},{text:H,style:"destructive",onPress:ce}])},z=()=>{if(!G){k(true);return}if(T){_.alert("Cannot Go Back","Already at the root of the stack");return}V()},Ce=()=>{if(!G){k(true);return}if(T){_.alert("Already at Top","Stack only has one screen");return}K("Pop to Top","This will remove all screens except the root screen.","Pop to Top",N)},ye=f=>{D(P===f?null:f)},xe=()=>{if(!G){k(true);return}if(R){if(R.isFocused){_.alert("Already There","This route is already visible");return}$(R.index)}},le=()=>{if(!G){k(true);return}if(!R)return;if(R.isFocused){_.alert("Cannot Pop","Selected route is already visible");return}if(R.index===v-1){_.alert("Cannot Pop","No screens above selected route");return}let f=v-1-R.index,E=R.index;K("Pop to Route",`Remove ${f} screen${f!==1?"s":""} above ${R.pathname}?`,"Pop",()=>ae(E))};return oe(c,{style:[h.container,e],children:[C(Ue,{testID:"buoy-routes-stack-scroll",style:h.stackScroll,contentContainerStyle:[h.stackContent,{paddingBottom:h.stackContent.padding+n.bottom}],children:[...u].reverse().map((f,E)=>{let H=u.length-1-E,ce=P===H,b=Object.keys(f.params).length>0,w=xa(H);return C(c,{style:h.stackItemWrapper,testID:w,children:oe(c,{style:[h.stackItem,ce&&h.stackItemSelected],children:[oe(W,{style:h.stackItemHeader,onPress:()=>ye(H),activeOpacity:.7,testID:`${w}-toggle`,accessibilityRole:"button",accessibilityLabel:`${f.pathname}, ${f.isFocused?"focused":"mounted"}, position ${H} of ${v-1}`,children:[C(c,{style:h.expandIndicator,children:ce?C(Ra,{size:14,color:j.color.textSecondary}):C(wa,{size:14,color:j.color.textSecondary})}),C(p,{style:h.stackItemPath,numberOfLines:1,testID:`${w}-path`,children:f.pathname}),C(Ia,{value:f.pathname,buttonStyle:h.copyRouteButton,testID:`${w}-copy`}),C(c,{style:[h.statusBadge,{backgroundColor:f.isFocused?`${Ze.success}15`:"#3B82F615",borderColor:f.isFocused?`${Ze.success}40`:"#3B82F640"}],children:C(p,{style:[h.statusBadgeText,{color:f.isFocused?Ze.success:"#3B82F6"}],testID:`${w}-status`,children:f.isFocused?"FOCUSED":"MOUNTED"})})]}),ce&&oe(c,{style:h.expandedContent,children:[oe(c,{style:h.detailRow,children:[C(p,{style:h.detailLabel,children:"Route Name:"}),C(p,{style:h.detailValue,testID:`${w}-name`,children:f.name})]}),oe(c,{style:h.detailRow,children:[C(p,{style:h.detailLabel,children:"Position:"}),oe(p,{style:h.detailValue,testID:`${w}-position`,children:[H," / ",v-1]})]}),b&&C(c,{style:h.dataViewerContainer,children:C(Pa,{title:"Parameters",data:f.params,showTypeFilter:false})}),oe(c,{style:h.actionsRow,children:[oe(c,{style:h.actionWrapper,children:[C(W,{style:[h.actionButton,T&&h.actionButtonDisabled],onPress:z,disabled:T,testID:`${w}-back`,accessibilityRole:"button",accessibilityLabel:"Go back one screen",children:C(p,{style:[h.actionButtonText,T&&h.actionButtonTextDisabled],children:"Back"})}),C(p,{style:h.helpText,children:"Go back one screen"})]}),oe(c,{style:h.actionWrapper,children:[C(W,{style:[h.actionButton,f.isFocused&&h.actionButtonDisabled],onPress:xe,disabled:f.isFocused,testID:`${w}-go`,accessibilityRole:"button",accessibilityLabel:`Navigate to ${f.pathname}`,children:C(p,{style:[h.actionButtonText,f.isFocused&&h.actionButtonTextDisabled],children:"Go"})}),C(p,{style:h.helpText,children:"Navigate to this route"})]}),oe(c,{style:h.actionWrapper,children:[C(W,{style:[h.actionButton,(f.isFocused||H===v-1)&&h.actionButtonDisabled],onPress:le,disabled:f.isFocused||H===v-1,testID:`${w}-pop-to`,accessibilityRole:"button",accessibilityLabel:`Remove screens above ${f.pathname}`,children:C(p,{style:[h.actionButtonText,(f.isFocused||H===v-1)&&h.actionButtonTextDisabled],children:"Pop To"})}),C(p,{style:h.helpText,children:"Remove screens above this"})]})]})]})]})},`stack-${H}-${f.key}`)})}),C(ka,{visible:ee,onClose:()=>k(false),featureName:"Stack Navigation"})]})}var h=ve.create({container:{flex:1,backgroundColor:"transparent"},loadingContainer:{flex:1,justifyContent:"center",alignItems:"center",padding:32},loadingText:{color:j.color.textSecondary,fontSize:14,fontFamily:se},errorContainer:{flex:1,justifyContent:"center",alignItems:"center",padding:32},errorText:{color:Ze.error,fontSize:16,fontWeight:"600",fontFamily:se,marginBottom:8},errorDetail:{color:j.color.textSecondary,fontSize:12,fontFamily:se,textAlign:"center"},emptyContainer:{flex:1,justifyContent:"center",alignItems:"center",padding:32},emptyText:{color:j.color.text,fontSize:16,fontWeight:"600",fontFamily:se,marginBottom:8},emptySubtext:{color:j.color.textSecondary,fontSize:14,fontFamily:se,textAlign:"center"},stackScroll:{flex:1},stackContent:{padding:8},stackItemWrapper:{marginBottom:6},stackItem:{backgroundColor:j.color.surface,borderRadius:6,borderWidth:1,borderColor:j.color.border,overflow:"hidden"},stackItemSelected:{borderColor:j.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:j.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:j.color.border},detailRow:{marginBottom:8},detailLabel:{fontSize:10,color:j.color.textSecondary,fontFamily:se,marginBottom:2},detailValue:{fontSize:12,color:j.color.text,fontFamily:se},dataViewerContainer:{marginTop:4,marginHorizontal:-12,marginBottom:8},actionsRow:{flexDirection:"row",gap:6,marginTop:12},actionWrapper:{flex:1},actionButton:{backgroundColor:j.color.surfaceElevated,paddingVertical:8,paddingHorizontal:8,borderRadius:6,alignItems:"center"},actionButtonDisabled:{opacity:.5},actionButtonText:{fontSize:12,fontWeight:"600",color:j.color.text,fontFamily:se},actionButtonTextDisabled:{color:j.color.textTertiary},helpText:{fontSize:9,color:j.color.textSecondary,fontFamily:se,textAlign:"center",marginTop:4,lineHeight:12}});import{useCallback as za}from"react";import{Navigation as Aa,night as gt,EVENT_LIST_PRESET as Na,monoFont as Zt}from"@buoy-gg/shared-ui/web";import{memo as Wa,useMemo as de}from"react";import{CompactRow as ja,RelativeTime as Va,buoyColors as Xt,night as Xe,monoFont as Yt}from"@buoy-gg/shared-ui/web";import{jsx as je}from"react/jsx-runtime";function Oa(e){return e.pathname==="/"?"home":ct(e.pathname,e.segments)?"dynamic":e.params&&Object.keys(e.params).length>0?"with-params":"default"}function Ha(e){switch(e){case"home":return Xt.success;case"dynamic":return Xe.color.accent;case"with-params":return Xt.warning;default:return Xe.color.textSecondary}}function Ma(e){switch(e){case"home":return"Home";case"dynamic":return"Dynamic";case"with-params":return"Params";default:return"Static"}}function Ua(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 Ga(e){let t=[];e.timeSincePrevious!==void 0&&e.timeSincePrevious>0&&t.push(Ua(e.timeSincePrevious));let o=e.segments?.length||0;return o>0&&t.push(`depth ${o}`),t.join(" \xB7 ")||"root"}function Ka(e){if(e.params&&Object.keys(e.params).length>0){let t=Object.keys(e.params).length;return`${t} PARAM${t!==1?"S":""}`}}var eo=Wa(function({event:e,visitNumber:t,isExpanded:o,onPress:r,onNavigate:a,index:i}){let n=de(()=>Oa(e),[e]),u=de(()=>ct(e.pathname,e.segments),[e.pathname,e.segments]),s=de(()=>Ha(n),[n]),m=de(()=>Ma(n),[n]),I=de(()=>Ga(e),[e]),v=de(()=>Ka(e),[e]),T=de(()=>ba(e.pathname,t),[e.pathname,t]),$=de(()=>`${e.pathname}, ${m}, ${I}`,[e.pathname,m,I]),ae=de(()=>{if(o)return je(lt,{event:e,visitNumber:t,routeTemplate:u})},[o,e,t,u]),V=de(()=>{if(a)return je(W,{style:to.goButton,onPress:()=>a(Nt(e.pathname,e.params)),testID:`${T}-go`,accessibilityRole:"button",accessibilityLabel:`Go to ${e.pathname}`,children:je(p,{style:to.goButtonText,children:"Go"})})},[a,e.pathname,T]);return je(ja,{statusDotColor:s,statusLabel:m,statusSublabel:I,primaryText:e.pathname,badgeText:v,badgeColor:s,trailingAction:V,bottomRightText:je(Va,{timestamp:e.timestamp}),showChevron:true,expandedContent:ae,isExpanded:o,expandedGlowColor:s,onPress:()=>r(i),testID:T,statusTestID:`${T}-status`,statusSublabelTestID:`${T}-sublabel`,accessibilityLabel:$})}),to=ve.create({badgeText:{fontSize:11,fontWeight:"600",fontFamily:Yt},goButton:{backgroundColor:Xe.color.accent,paddingHorizontal:8,paddingVertical:4,borderRadius:4},goButtonText:{fontSize:10,fontWeight:"600",color:Xe.color.onAccent,fontFamily:Yt}});import{jsx as Ve,jsxs as _a}from"react/jsx-runtime";function Ja({events:e,visitCounts:t,onNavigate:o,onSelectEvent:r}){let a=za(i=>{let n=e[i];n&&r(n,t.get(n)||1)},[e,t,r]);return e.length===0?_a(c,{style:Ye.emptyState,testID:"buoy-routes-empty",children:[Ve(Aa,{size:48,color:gt.color.textTertiary}),Ve(p,{style:Ye.emptyTitle,testID:"buoy-routes-empty-title",children:"No events yet"}),Ve(p,{style:Ye.emptySubtitle,testID:"buoy-routes-empty-subtitle",children:"Navigation events will appear here"})]}):Ve(Pt,{testID:"buoy-routes-timeline",contentContainerStyle:Ye.listContent,data:e,keyExtractor:i=>`${i.timestamp}-${i.pathname}`,renderItem:({item:i,index:n})=>Ve(eo,{event:i,visitNumber:t.get(i)||1,isExpanded:false,index:n,onPress:a,onNavigate:o}),showsVerticalScrollIndicator:true,...Na})}var Ye=ve.create({listContent:{paddingVertical:8},emptyState:{flex:1,justifyContent:"center",alignItems:"center",padding:32},emptyTitle:{color:gt.color.text,fontSize:16,fontWeight:"600",marginTop:16,marginBottom:8,fontFamily:Zt,letterSpacing:.5,textTransform:"uppercase"},emptySubtitle:{color:gt.color.textSecondary,fontSize:14,textAlign:"center",fontFamily:Zt}});import{Fragment as Qa,jsx as S,jsxs as re}from"react/jsx-runtime";var yt=Rr(),qa={parse:e=>e==="routes"||e==="events"||e==="stack"?e:void 0,serialize:e=>e},Za={parse:e=>e==="true",serialize:e=>e.toString()},Xa={parse:e=>new Set(JSON.parse(e)),serialize:e=>JSON.stringify(Array.from(e))};function oo(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=oo(o.state,t);if(r)return[o.name,...r]}}return null}function Ya(e,t){if(e.length===0)return null;let o=t&&Object.keys(t).length>0?t:void 0;if(e.length===1)return yt.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 yt.navigate({name:e[0],params:r})}function ft({visible:e,onClose:t,onBack:o,onMinimize:r,enableSharedModalDimensions:a=false,inline:i=false,remote:n}){let u=wr(),s=void 0,m=Ir(),[I,v]=at($e.routeEvents.activeTab(),"events",qa),[T,$]=we(false),[ae,V]=we(""),N=Vr(),P=jr("routeEvents.entries");Bt(()=>{T&&N&&$(false)},[T,N]);let[D,ee]=at($e.routeEvents.isMonitoring(),true,Za),{events:k,clearEvents:G,isListening:pe}=At({enabled:D}),R=D&&pe;Bt(()=>{he.setBootCapture(D)},[D]);let[O,K]=we(false),[z,Ce]=we(null),[ye,xe]=we(1),[le,f]=we(""),[E,H]=at($e.routeEvents.eventFilters(),new Set(["/_sitemap","/api","/__dev"]),Xa),ce=wo(null),b=ue(g=>{},[]),w=ue(g=>{try{if(n){if(!n.onNavigatePath)return;if(!N&&g!=="/"){$(true);return}n.onNavigatePath(g);return}if(m)u.push(g);else if(s){let{pathname:B,params:q}=qr(g),me=B.startsWith("/")?B.slice(1):B,Te=Object.keys(q).length>0,Re=s.getRootState?.();if(Re){let Me=oo(Re,me);if(Me){let wt=Ya(Me,q);if(wt){s.dispatch(wt);return}}}s.dispatch(yt.navigate(Te?{name:me,params:q}:{name:me}))}else _.alert("Navigation Unavailable","No Expo Router or React Navigation container was found in this app.")}catch(B){_.alert("Navigation Error",String(B))}},[u,s,m,n,N]),X=ue(()=>{ee(g=>!g)},[]),Pe=ue(()=>{if(k.length!==0){if(!N){$(true);return}G()}},[k.length,N,G]),Le=ue(g=>{H(B=>{let q=new Set(B);return q.has(g)?q.delete(g):q.add(g),q})},[]),et=ue(g=>{H(B=>new Set([...B,g]))},[]),ne=ue(()=>{K(!O)},[O]),fe=ue((g,B)=>{Ce(g),xe(B)},[]),He=ue(()=>{Ce(null)},[]),mo=ue(g=>{Ce(null),v(g)},[]),ho=Ie(()=>{let g=new Set;return k.forEach(B=>{B.pathname&&g.add(B.pathname)}),Array.from(g).sort()},[k]),be=Ie(()=>k.filter(g=>{if(!g.pathname||Array.from(E).some(B=>g.pathname.includes(B)))return false;if(le.trim()){let B=le.toLowerCase(),q=g.pathname.toLowerCase().includes(B),me=Object.entries(g.params||{}).some(([Te,Re])=>{let Me=Array.isArray(Re)?Re.join(" "):Re;return Te.toLowerCase().includes(B)||Me.toLowerCase().includes(B)});return q||me}return true}),[k,E,le]),go=Ie(()=>be.slice(0,P),[be,P]),tt=Ie(()=>Math.max(0,be.length-P),[be.length,P]),ot=Ie(()=>{let g=new Map,B=new Map;for(let q=k.length-1;q>=0;q--){let me=k[q],Te=(g.get(me.pathname)||0)+1;g.set(me.pathname,Te),B.set(me,Te)}return B},[k]),yo=Ie(()=>({summary:{total:k.length,filtered:be.length,listening:R,ignoredPatterns:Array.from(E),timestamp:new Date().toISOString()},events:be.map((g,B)=>({index:B,visitNumber:ot.get(g)||1,pathname:g.pathname,timestamp:g.timestamp,timestampRelative:Lr(g.timestamp),params:g.params,segments:g.segments,previousPathname:g.previousPathname,timeSincePrevious:g.timeSincePrevious}))}),[k.length,be,R,E,ot]);if(!e)return null;let fo=a?$e.modal.root():$e.routeEvents.modal(),rt=null,Ct=()=>{if(z)return S(jt,{event:z,visitNumber:ye,onNavigate:w});if(I==="routes")return m||n?.sitemap?S(ht,{style:A.contentWrapper,injectedRoutes:n?.sitemap?.routes,injectedSource:n?.sitemap?.source??null,injectedLastUpdatedAt:n?.sitemap?.lastUpdatedAt??null,onNavigateRoute:n?bo:void 0}):S(ht,{style:A.contentWrapper});if(I==="stack")return S(qt,{style:A.contentWrapper,injectedStack:n?n.stack??[]:void 0,onAction:n?.onStackAction,onCopyValueChange:V});if(O)return S(Yr,{ignoredPatterns:E,onTogglePattern:Le,onAddPattern:et,availablePathnames:ho});let g=k.length>0;return be.length===0?re(c,{style:A.contentWrapper,testID:"buoy-routes-events",children:[g&&S(c,{style:A.searchContainer,testID:"buoy-routes-search-field",children:S($t,{value:le,onChange:f,placeholder:"Search pathname or params...",testID:"buoy-routes-search"})}),S(Br,{testID:"buoy-routes-empty",...Dr({subject:"route events",search:le,total:k.length,capturing:R,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"}})})]}):re(c,{style:A.contentWrapper,testID:"buoy-routes-events",children:[S(c,{style:A.searchContainer,testID:"buoy-routes-search-field",children:S($t,{value:le,onChange:f,placeholder:"Search pathname or params...",testID:"buoy-routes-search"})}),tt>0&&re(c,{style:A.lockedEventsBanner,testID:"buoy-routes-locked-banner",children:[S(zr,{size:14,color:M.color.warning}),re(p,{style:A.lockedEventsBannerText,testID:"buoy-routes-locked-banner-text",children:[tt," older ",tt===1?"event":"events"," locked"]}),S(p,{style:A.lockedEventsBannerSubtext,children:"Upgrade to Pro for full history"})]}),S(Ja,{events:go,visitCounts:ot,onNavigate:w,onSelectEvent:fe})]})},Tt=z?re(ie,{children:[S(ie.Navigation,{onBack:He}),S(ie.Content,{title:z.pathname,testID:"buoy-routes-detail-title"}),S(ie.Actions,{children:S(nt,{testID:"buoy-routes-detail-copy",value:{pathname:z.pathname,previousPathname:z.previousPathname,params:z.params,segments:z.segments,timestamp:z.timestamp,timestampISO:new Date(z.timestamp).toISOString(),timeSincePrevious:z.timeSincePrevious,visitNumber:ye},buttonStyle:A.iconButton})})]}):O?re(ie,{children:[S(ie.Navigation,{onBack:()=>K(false)}),S(ie.Content,{title:"Filters",testID:"buoy-routes-filters-title"})]}):re(ie,{children:[o&&S(ie.Navigation,{onBack:o}),S(ie.Content,{title:"",noMargin:true,children:S(Pr,{tabs:[{key:"routes",label:m?"Routes":"Screens"},{key:"events",label:`Events${k.length>0&&I!=="events"?` (${k.length})`:""}`},{key:"stack",label:"Stack"}],activeTab:I,onTabChange:g=>mo(g),testIDPrefix:"buoy-routes-tab"})}),re(ie.Actions,{children:[I==="stack"&&S(nt,{value:ae,buttonStyle:A.iconButton,testID:"buoy-routes-stack-copy"}),I==="events"&&re(Qa,{children:[S(nt,{value:yo,buttonStyle:A.iconButton,testID:"buoy-routes-copy"}),S(W,{onPress:ne,style:[A.iconButton,E.size>0&&A.activeFilterButton],testID:"buoy-routes-filters",accessibilityRole:"button",accessibilityLabel:E.size>0?`Route filters, ${E.size} active`:"Route filters",children:S(Fr,{size:14,color:E.size>0?M.color.accent:M.color.textSecondary})}),S(Nr,{isEnabled:R,onToggle:X,accessibilityLabel:"Toggle route event monitoring",testID:"buoy-routes-power"}),S(W,{onPress:Pe,style:A.iconButton,testID:"buoy-routes-clear",accessibilityRole:"button",accessibilityLabel:"Clear route events",children:S($r,{size:14,color:M.color.danger})})]})]})]}),bo=g=>{if(g.type==="layout"||g.type==="group")return;let B=g.type==="index"||g.path==="/";if(!N&&!B){$(true);return}n?.onNavigateRoute?.(g)},Rt=S(Ar,{visible:T,onClose:()=>$(false),featureName:"Route Event Management"});return i?re(Ft,{children:[re(c,{style:A.inlineRoot,children:[S(c,{style:A.inlineHeader,...kr,children:Tt}),Ct(),rt]}),Rt]}):S(Ft,{children:re(Er,{visible:e,onClose:t,onMinimize:r,persistenceKey:fo,header:{showToggleButton:true,customContent:Tt},onModeChange:b,enablePersistence:true,initialMode:"bottomSheet",enableGlitchEffects:true,disableScrollWrapper:true,styles:{},footer:rt,footerHeight:rt?68:0,children:[Ct(),Rt]})})}function en(e={}){return S(ft,{...e,inline:true,visible:true,onClose:()=>{}})}var A=ve.create({inlineRoot:{flex:1,minHeight:0,backgroundColor:"transparent"},inlineHeader:{paddingHorizontal:12,paddingVertical:8,borderBottomWidth:1,borderBottomColor:Wr.border,backgroundColor:"transparent"},iconButton:{padding:6,borderRadius:6,backgroundColor:M.color.buttonSurface},activeFilterButton:{backgroundColor:M.color.accentSoft},emptyState:{flex:1,justifyContent:"center",alignItems:"center",padding:32},emptyTitle:{color:M.color.text,fontSize:16,fontWeight:"600",marginTop:16,marginBottom:8,fontFamily:Ge,letterSpacing:.5,textTransform:"uppercase"},emptySubtitle:{color:M.color.textSecondary,fontSize:14,textAlign:"center",fontFamily:Ge},contentWrapper:{flex:1},statsContainer:{paddingHorizontal:16,paddingVertical:8,backgroundColor:M.color.surface,borderBottomWidth:1,borderBottomColor:M.color.border},statsText:{fontSize:11,color:M.color.textSecondary,fontFamily:Ge,textAlign:"center"},statsWarning:{color:M.color.warning,fontWeight:"600"},searchContainer:{paddingHorizontal:16,paddingVertical:8,backgroundColor:"transparent"},lockedEventsBanner:{flexDirection:"row",alignItems:"center",gap:8,backgroundColor:M.color.warningSoft,borderWidth:1,borderColor:M.color.warning+"30",borderRadius:8,paddingVertical:10,paddingHorizontal:14,marginHorizontal:16,marginBottom:8},lockedEventsBannerText:{fontSize:12,fontWeight:"600",color:M.color.warning,fontFamily:Ge},lockedEventsBannerSubtext:{fontSize:11,color:M.color.textSecondary,marginLeft:"auto"}});import{createToolFactory as tn,defineToolPreset as on}from"@buoy-gg/shared-ui/web";import{jsx as rn}from"react/jsx-runtime";var ro=on({id:"route-events",name:"ROUTES",description:"Route tracking & navigation inspector",slot:"both",icon:({size:e})=>rn(Ro,{size:e}),component:ft,props:{enableSharedModalDimensions:false}}),an=tn(ro,e=>({enableSharedModalDimensions:e.enableSharedModalDimensions??false}));import{useEffect as nn}from"react";import{browserRouter as ao,getBrowserHref as sn,getBrowserRouteURL as no,subscribeBrowserNavigation as ln}from"@buoy-gg/shared-ui/web/utils";var io=0,bt;function cn(){if(typeof window>"u")return()=>{};if(io++===0){he.hydrateBootCapture();let t,o,r="",a=[],i=-1,n=s=>{if(s.href===r&&s.kind==="pop")return;if(s.kind==="replace"&&i>=0)a[i]=s.href;else if(s.kind==="pop"){let v=a.lastIndexOf(s.href,i-1),T=a.indexOf(s.href,i+1);v>=0?i=v:T>=0?i=T:(a.splice(i+1),a.push(s.href),i++)}else a.splice(i+1),a.push(s.href),i++;r=s.href;let m=no(s.href),I=Date.now();Fe.emit({pathname:m.pathname,params:Object.fromEntries(m.searchParams),segments:m.pathname.split("/").filter(Boolean),previousPathname:t,timestamp:I,timeSincePrevious:o===void 0?void 0:I-o}),t=m.pathname,o=I,Q.setStack(a.map((v,T)=>{let $=no(v);return{key:`browser:${T}`,name:$.pathname,pathname:$.pathname,params:Object.fromEntries($.searchParams),index:T,isFocused:T===i,canPop:T>0}}))},u=s=>{if(!Number.isInteger(s)||s<0||s>=a.length)throw new Error("That browser history entry is unavailable.");window.history.go(s-i)};Q.setActions({navigateToIndex:u,popToIndex:u,goBack:ao.back,popToTop:()=>u(0),navigateToRoute:(s,m)=>(ao.push({pathname:s,params:m}),true)}),bt=ln(n),n({href:sn(),kind:"initial"})}let e=false;return()=>{e||(e=true,--io===0&&(bt?.(),bt=void 0,Q.setActions(null)))}}function un(){return nn(cn,[]),null}import{useEffect as so,useRef as vt}from"react";import{useSafePathname as dn,useSafeSegments as pn,useSafeGlobalSearchParams as mn}from"@buoy-gg/shared-ui/web";function hn(e){let t=dn(),o=pn(),r=mn(),a=vt(e),i=vt(void 0),n=vt(void 0);so(()=>{a.current=e},[e]),so(()=>{let u=Date.now(),s=n.current?u-n.current:void 0,m={pathname:t,params:r,segments:o,timestamp:u,previousPathname:i.current,timeSincePrevious:s};i.current=t,n.current=u,Fe.emit(m),a.current&&a.current(m)},[t,o,r])}import{useEffect as lo,useRef as xt}from"react";function co(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=co(t.state);if(r.route)return{route:r.route,segments:[...o,...r.segments]}}return{route:t,segments:o}}function uo(e,t,o,r){if(!e)return;let{route:a,segments:i}=co(e);if(!a)return;let n=`/${a.name}`;if(n===t.current)return;let u=Date.now(),s=o.current?u-o.current:void 0,m={pathname:n,params:a.params||{},segments:i,timestamp:u,previousPathname:t.current,timeSincePrevious:s};t.current=n,o.current=u,Fe.emit(m),r.current&&r.current(m)}function gn(e){let t=void 0,o=xt(e),r=xt(void 0),a=xt(void 0);lo(()=>{o.current=e},[e]),lo(()=>{if(!t)return;let i=t.getRootState?.();i&&uo(i,r,a,o);let n=t.addListener?.("state",()=>{let u=t.getRootState?.();uo(u,r,a,o)});return()=>{n?.()}},[t])}import{getSafeRouter as yn}from"@buoy-gg/shared-ui/web";function fn(e,t){let o=[],r=false,a=u=>{for(let s of u??[])(s.name?.includes("+not-found")||s.path?.includes("+not-found"))&&(r=true),typeof s.path=="string"&&o.push(s.path),a(s.children)};if(a(t),r||o.length===0)return;let i=u=>"/"+u.split("?")[0].split("#")[0].split("/").filter(s=>s&&!/^\(.*\)$/.test(s)).join("/"),n=i(e);return o.some(u=>{let s=i(u);return s===n?true:new RegExp("^"+s.split("/").map(m=>/^\[\.\.\..+\]$/.test(m)?".+":/^\[.+\]$/.test(m)?"[^/]+":m.replace(/[.*+?^${}()|\\]/g,"\\$&")).join("/")+"$").test(n)})}import{isOverWireBudget as bn}from"@buoy-gg/shared-ui/web";var vn=16*1024,xn=Object.freeze({__buoyOmitted:"route-params",note:"Navigation params stay on the device."});function St(e){return e==null?false:bn(e,vn)}function Oe(e){return St(e)?xn:e}function Sn(e){return St(e.params)?{...e,params:Oe(e.params)}:e}function Cn(e){return St(e.params)?{...e,params:Oe(e.params)}:e}function po(){let e=pt();return{routes:ge.parseRouteTree(We()),source:e.source,lastUpdatedAt:e.lastLoadedAt}}var Tn={version:3,getSnapshot:()=>({events:he.getEvents().map(Sn),sitemap:po(),stack:Q.getStack().map(Cn)}),subscribe:e=>{let t=he.subscribeToEvents(e),o=Q.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=Q.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=yn();if(!r){let i=Q.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=po().routes}catch{a=[]}if(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){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=Q.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=Q.getActions();if(!o)throw new Error("navigation stack is not available");return o.popToIndex(t),{poppedToIndex:t}},stackGoBack:()=>{let e=Q.getActions();if(!e)throw new Error("navigation stack is not available");return e.goBack(),{wentBack:true}},stackPopToTop:()=>{let e=Q.getActions();if(!e)throw new Error("navigation stack is not available");return e.popToTop(),{poppedToTop:true}}}};export{qt as NavigationStack,jt as RouteEventDetail,lt as RouteEventExpandedContent,eo as RouteEventItemCompact,ft as RouteEventsModalWithTabs,zt as RouteObserver,ge as RouteParser,un as RouteTracker,ht as RoutesSitemap,en as RoutesToolView,an as createRouteEventsTool,Q as navigationStackStore,ma as registerBrowserRoutes,he as routeEventStore,Tn as routeEventsSyncAdapter,ro as routeEventsToolPreset,Fe as routeObserver,Qt as useNavigationStack,fa as useParentRoutes,ya as useRoute,At as useRouteEvents,hn as useRouteObserver,gn as useRouteObserverReactNavigation,Je 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.45",
|
|
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/floating-tools-core": "^7.0.
|
|
38
|
-
"@buoy-gg/shared-ui": "^7.0.
|
|
37
|
+
"@buoy-gg/floating-tools-core": "^7.0.45",
|
|
38
|
+
"@buoy-gg/shared-ui": "^7.0.45"
|
|
39
39
|
},
|
|
40
40
|
"peerDependencies": {
|
|
41
|
-
"@buoy-gg/license": "7.0.
|
|
41
|
+
"@buoy-gg/license": "7.0.45",
|
|
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.45"
|
|
69
69
|
},
|
|
70
70
|
"react-native-builder-bob": {
|
|
71
71
|
"source": "src",
|