@buoy-gg/route-events 7.0.41 → 7.0.43
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -64
- package/lib/commonjs/RouteObserver.js +1 -54
- package/lib/commonjs/RouteParser.js +1 -314
- package/lib/commonjs/RouteTracker.js +1 -112
- package/lib/commonjs/RouteTracker.web.js +1 -12
- package/lib/commonjs/browserRouteRegistry.js +1 -30
- package/lib/commonjs/browserRoutes.js +1 -96
- package/lib/commonjs/components/NavigationStack.js +2 -572
- package/lib/commonjs/components/ReactNavigationRoutes.js +1 -836
- package/lib/commonjs/components/ReactNavigationRoutes.web.js +1 -12
- package/lib/commonjs/components/RouteEventDetail.js +1 -97
- package/lib/commonjs/components/RouteEventExpandedContent.js +1 -204
- package/lib/commonjs/components/RouteEventItemCompact.js +1 -191
- package/lib/commonjs/components/RouteEventsModalWithTabs.js +1 -734
- package/lib/commonjs/components/RouteEventsTimeline.js +1 -107
- package/lib/commonjs/components/RouteFilterViewV2.js +1 -42
- package/lib/commonjs/components/RoutesSitemap.js +2 -1035
- package/lib/commonjs/expoRouterStore.js +1 -121
- package/lib/commonjs/expoRouterStore.web.js +1 -44
- package/lib/commonjs/hooks/useRouteEvents.js +1 -57
- package/lib/commonjs/index.js +1 -168
- package/lib/commonjs/preset.js +1 -69
- package/lib/commonjs/stores/navigationStackStore.js +1 -45
- package/lib/commonjs/stores/routeEventStore.js +1 -136
- package/lib/commonjs/sync/routeEventsSyncAdapter.js +1 -275
- package/lib/commonjs/useNavigationStack.js +1 -408
- package/lib/commonjs/useNavigationStack.web.js +1 -32
- package/lib/commonjs/useRouteObserver.js +1 -73
- package/lib/commonjs/useRouteObserverReactNavigation.js +1 -109
- package/lib/commonjs/useRouteSitemap.js +1 -255
- package/lib/commonjs/utils/routeTemplate.js +1 -79
- package/lib/commonjs/utils/safeReactNavigation.js +1 -194
- package/lib/commonjs/utils/safeReactNavigation.web.js +1 -36
- package/lib/commonjs/utils/testIDs.js +1 -63
- package/lib/module/RouteObserver.js +1 -49
- package/lib/module/RouteParser.js +1 -309
- package/lib/module/RouteTracker.js +1 -109
- package/lib/module/RouteTracker.web.js +1 -8
- package/lib/module/browserRouteRegistry.js +1 -24
- package/lib/module/browserRoutes.js +1 -92
- package/lib/module/components/NavigationStack.js +2 -568
- package/lib/module/components/ReactNavigationRoutes.js +1 -832
- package/lib/module/components/ReactNavigationRoutes.web.js +1 -3
- package/lib/module/components/RouteEventDetail.js +1 -93
- package/lib/module/components/RouteEventExpandedContent.js +1 -200
- package/lib/module/components/RouteEventItemCompact.js +1 -187
- package/lib/module/components/RouteEventsModalWithTabs.js +1 -731
- package/lib/module/components/RouteEventsTimeline.js +1 -103
- package/lib/module/components/RouteFilterViewV2.js +1 -38
- package/lib/module/components/RoutesSitemap.js +2 -1033
- package/lib/module/expoRouterStore.js +1 -114
- package/lib/module/expoRouterStore.web.js +1 -37
- package/lib/module/hooks/useRouteEvents.js +1 -54
- package/lib/module/index.js +1 -70
- package/lib/module/preset.js +1 -66
- package/lib/module/stores/navigationStackStore.js +1 -41
- package/lib/module/stores/routeEventStore.js +1 -128
- package/lib/module/sync/routeEventsSyncAdapter.js +1 -273
- package/lib/module/useNavigationStack.js +1 -404
- package/lib/module/useNavigationStack.web.js +1 -28
- package/lib/module/useRouteObserver.js +1 -70
- package/lib/module/useRouteObserverReactNavigation.js +1 -106
- package/lib/module/useRouteSitemap.js +1 -250
- package/lib/module/utils/routeTemplate.js +1 -73
- package/lib/module/utils/safeReactNavigation.js +1 -185
- package/lib/module/utils/safeReactNavigation.web.js +1 -27
- package/lib/module/utils/testIDs.js +1 -55
- package/lib/web/index.mjs +4 -5
- package/package.json +6 -11
- package/lib/typescript/RouteObserver.d.ts.map +0 -1
- package/lib/typescript/RouteParser.d.ts.map +0 -1
- package/lib/typescript/RouteTracker.d.ts.map +0 -1
- package/lib/typescript/RouteTracker.web.d.ts.map +0 -1
- package/lib/typescript/browserRouteRegistry.d.ts.map +0 -1
- package/lib/typescript/browserRoutes.d.ts.map +0 -1
- package/lib/typescript/components/NavigationStack.d.ts.map +0 -1
- package/lib/typescript/components/ReactNavigationRoutes.d.ts.map +0 -1
- package/lib/typescript/components/ReactNavigationRoutes.web.d.ts.map +0 -1
- package/lib/typescript/components/RouteEventDetail.d.ts.map +0 -1
- package/lib/typescript/components/RouteEventExpandedContent.d.ts.map +0 -1
- package/lib/typescript/components/RouteEventItemCompact.d.ts.map +0 -1
- package/lib/typescript/components/RouteEventsModalWithTabs.d.ts.map +0 -1
- package/lib/typescript/components/RouteEventsTimeline.d.ts.map +0 -1
- package/lib/typescript/components/RouteFilterViewV2.d.ts.map +0 -1
- package/lib/typescript/components/RoutesSitemap.d.ts.map +0 -1
- package/lib/typescript/expoRouterStore.d.ts.map +0 -1
- package/lib/typescript/expoRouterStore.web.d.ts.map +0 -1
- package/lib/typescript/hooks/useRouteEvents.d.ts.map +0 -1
- package/lib/typescript/index.d.ts.map +0 -1
- package/lib/typescript/preset.d.ts.map +0 -1
- package/lib/typescript/stores/navigationStackStore.d.ts.map +0 -1
- package/lib/typescript/stores/routeEventStore.d.ts.map +0 -1
- package/lib/typescript/sync/routeEventsSyncAdapter.d.ts.map +0 -1
- package/lib/typescript/useNavigationStack.d.ts.map +0 -1
- package/lib/typescript/useNavigationStack.web.d.ts.map +0 -1
- package/lib/typescript/useRouteObserver.d.ts.map +0 -1
- package/lib/typescript/useRouteObserverReactNavigation.d.ts.map +0 -1
- package/lib/typescript/useRouteSitemap.d.ts.map +0 -1
- package/lib/typescript/utils/routeTemplate.d.ts.map +0 -1
- package/lib/typescript/utils/safeReactNavigation.d.ts.map +0 -1
- package/lib/typescript/utils/safeReactNavigation.web.d.ts.map +0 -1
- package/lib/typescript/utils/testIDs.d.ts.map +0 -1
|
@@ -1,185 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Safe wrapper for @react-navigation/native
|
|
5
|
-
*
|
|
6
|
-
* Provides optional imports for React Navigation hooks.
|
|
7
|
-
* Falls back to no-op implementations when @react-navigation/native is not installed.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
import { createContext, useContext, useMemo } from "react";
|
|
11
|
-
let reactNavigation = null;
|
|
12
|
-
let isAvailable = false;
|
|
13
|
-
let checkedAvailability = false;
|
|
14
|
-
|
|
15
|
-
// Expo Router (SDK 54+) VENDORS React Navigation: its NavigationContainer
|
|
16
|
-
// provides the vendored NavigationContainerRefContext from
|
|
17
|
-
// expo-router/build/react-navigation, NOT the one exported by the
|
|
18
|
-
// @react-navigation/native package (which may not even be installed, or is a
|
|
19
|
-
// second module instance whose context nobody provides). Reading only the npm
|
|
20
|
-
// context in such apps yields undefined forever — the Stack tab then hangs on
|
|
21
|
-
// "Loading navigation stack...". So we load both copies and consult both
|
|
22
|
-
// contexts.
|
|
23
|
-
let vendoredReactNavigation = null;
|
|
24
|
-
let checkedVendored = false;
|
|
25
|
-
function getVendoredReactNavigation() {
|
|
26
|
-
if (checkedVendored) return vendoredReactNavigation;
|
|
27
|
-
checkedVendored = true;
|
|
28
|
-
try {
|
|
29
|
-
// Compat entry re-exporting the vendored native/core/routers modules.
|
|
30
|
-
// Older expo-router versions (and RN CLI apps) don't have it — the
|
|
31
|
-
// require throws and we stay on @react-navigation/native.
|
|
32
|
-
const vendored = require("expo-router/react-navigation");
|
|
33
|
-
vendoredReactNavigation = vendored?.NavigationContainerRefContext ? vendored : null;
|
|
34
|
-
} catch {
|
|
35
|
-
vendoredReactNavigation = null;
|
|
36
|
-
}
|
|
37
|
-
return vendoredReactNavigation;
|
|
38
|
-
}
|
|
39
|
-
function checkReactNavigationAvailability() {
|
|
40
|
-
if (checkedAvailability) return isAvailable;
|
|
41
|
-
try {
|
|
42
|
-
reactNavigation = require("@react-navigation/native");
|
|
43
|
-
isAvailable = reactNavigation != null;
|
|
44
|
-
} catch (error) {
|
|
45
|
-
isAvailable = false;
|
|
46
|
-
reactNavigation = null;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// Expo Router apps don't necessarily install @react-navigation/native at
|
|
50
|
-
// all — the vendored copy then supplies CommonActions/StackActions/hooks
|
|
51
|
-
// (actions are plain serializable objects, so either copy's work).
|
|
52
|
-
if (!isAvailable) {
|
|
53
|
-
const vendored = getVendoredReactNavigation();
|
|
54
|
-
if (vendored) {
|
|
55
|
-
reactNavigation = vendored;
|
|
56
|
-
isAvailable = true;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
checkedAvailability = true;
|
|
60
|
-
return isAvailable;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// ============================================================================
|
|
64
|
-
// No-op implementations when @react-navigation/native is not available
|
|
65
|
-
// ============================================================================
|
|
66
|
-
|
|
67
|
-
function noOpUseNavigation() {
|
|
68
|
-
return useMemo(() => ({
|
|
69
|
-
navigate: () => console.warn("[route-events] @react-navigation/native not installed: navigate() unavailable"),
|
|
70
|
-
goBack: () => console.warn("[route-events] @react-navigation/native not installed: goBack() unavailable"),
|
|
71
|
-
canGoBack: () => false,
|
|
72
|
-
reset: () => console.warn("[route-events] @react-navigation/native not installed: reset() unavailable"),
|
|
73
|
-
setParams: () => console.warn("[route-events] @react-navigation/native not installed: setParams() unavailable"),
|
|
74
|
-
dispatch: () => console.warn("[route-events] @react-navigation/native not installed: dispatch() unavailable"),
|
|
75
|
-
isFocused: () => true,
|
|
76
|
-
addListener: () => () => {},
|
|
77
|
-
removeListener: () => {},
|
|
78
|
-
getParent: () => undefined,
|
|
79
|
-
getState: () => undefined,
|
|
80
|
-
getId: () => undefined
|
|
81
|
-
}), []);
|
|
82
|
-
}
|
|
83
|
-
function noOpUseNavigationState(selector) {
|
|
84
|
-
return useMemo(() => {
|
|
85
|
-
// Return a minimal state structure
|
|
86
|
-
const emptyState = {
|
|
87
|
-
key: "default",
|
|
88
|
-
index: 0,
|
|
89
|
-
routeNames: [],
|
|
90
|
-
routes: [],
|
|
91
|
-
type: "stack"
|
|
92
|
-
};
|
|
93
|
-
try {
|
|
94
|
-
return selector ? selector(emptyState) : emptyState;
|
|
95
|
-
} catch {
|
|
96
|
-
return emptyState;
|
|
97
|
-
}
|
|
98
|
-
}, [selector]);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
// ============================================================================
|
|
102
|
-
// Safe hook exports
|
|
103
|
-
// ============================================================================
|
|
104
|
-
|
|
105
|
-
export function useSafeNavigation() {
|
|
106
|
-
if (!checkReactNavigationAvailability()) {
|
|
107
|
-
return noOpUseNavigation();
|
|
108
|
-
}
|
|
109
|
-
try {
|
|
110
|
-
return reactNavigation.useNavigation();
|
|
111
|
-
} catch (error) {
|
|
112
|
-
console.warn("[route-events] Failed to use @react-navigation/native.useNavigation:", error);
|
|
113
|
-
return noOpUseNavigation();
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
export function useSafeNavigationState(selector) {
|
|
117
|
-
if (!checkReactNavigationAvailability()) {
|
|
118
|
-
return noOpUseNavigationState(selector);
|
|
119
|
-
}
|
|
120
|
-
try {
|
|
121
|
-
return reactNavigation.useNavigationState(selector);
|
|
122
|
-
} catch (error) {
|
|
123
|
-
console.warn("[route-events] Failed to use @react-navigation/native.useNavigationState:", error);
|
|
124
|
-
return noOpUseNavigationState(selector);
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// ============================================================================
|
|
129
|
-
// Guarded module accessors
|
|
130
|
-
// ============================================================================
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* Fallback for useContext when @react-navigation/native is absent: a stable
|
|
134
|
-
* context that always yields undefined, so callers' `if (!containerRef)`
|
|
135
|
-
* guards skip every dispatch path. Module presence is constant for the app
|
|
136
|
-
* lifetime, so hook order stays stable either way.
|
|
137
|
-
*/
|
|
138
|
-
const FallbackNavigationContainerRefContext = /*#__PURE__*/createContext(undefined);
|
|
139
|
-
|
|
140
|
-
/** CommonActions from @react-navigation/native, or null when absent. */
|
|
141
|
-
export function getCommonActions() {
|
|
142
|
-
return checkReactNavigationAvailability() ? reactNavigation.CommonActions : null;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/** StackActions from @react-navigation/native, or null when absent. */
|
|
146
|
-
export function getStackActions() {
|
|
147
|
-
return checkReactNavigationAvailability() ? reactNavigation.StackActions : null;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// Both contexts are resolved ONCE and cached so hook identity/order stays
|
|
151
|
-
// stable for the app lifetime (module presence is constant).
|
|
152
|
-
let npmContainerRefContext = null;
|
|
153
|
-
let vendoredContainerRefContext = null;
|
|
154
|
-
function getContainerRefContexts() {
|
|
155
|
-
if (npmContainerRefContext == null) {
|
|
156
|
-
npmContainerRefContext = checkReactNavigationAvailability() && reactNavigation.NavigationContainerRefContext ? reactNavigation.NavigationContainerRefContext : FallbackNavigationContainerRefContext;
|
|
157
|
-
}
|
|
158
|
-
if (vendoredContainerRefContext == null) {
|
|
159
|
-
const vendored = getVendoredReactNavigation();
|
|
160
|
-
vendoredContainerRefContext = vendored?.NavigationContainerRefContext ?? FallbackNavigationContainerRefContext;
|
|
161
|
-
}
|
|
162
|
-
return [npmContainerRefContext, vendoredContainerRefContext];
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* The navigation container ref for THIS app, whichever module instance
|
|
167
|
-
* provides it: @react-navigation/native's NavigationContainerRefContext
|
|
168
|
-
* (RN CLI, older expo-router) or Expo Router's vendored copy (SDK 54+).
|
|
169
|
-
* Returns undefined when rendered outside any NavigationContainer or when
|
|
170
|
-
* React Navigation is absent entirely.
|
|
171
|
-
*/
|
|
172
|
-
export function useSafeNavigationContainerRef() {
|
|
173
|
-
const [npmCtx, vendoredCtx] = getContainerRefContexts();
|
|
174
|
-
const npmRef = useContext(npmCtx);
|
|
175
|
-
const vendoredRef = useContext(vendoredCtx);
|
|
176
|
-
return npmRef ?? vendoredRef;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
// ============================================================================
|
|
180
|
-
// Availability check
|
|
181
|
-
// ============================================================================
|
|
182
|
-
|
|
183
|
-
export function isReactNavigationAvailable() {
|
|
184
|
-
return checkReactNavigationAvailability();
|
|
185
|
-
}
|
|
1
|
+
"use strict";import{createContext as p,useContext as l,useMemo as c}from"react";let t=null;let a=false;let s=false;let o=null;let v=false;function f(){if(v)return o;v=true;try{const e=require("expo-router/react-navigation");o=e?.NavigationContainerRefContext?e:null}catch{o=null}return o}function i(){if(s)return a;try{t=require("@react-navigation/native");a=t!=null}catch(e){a=false;t=null}if(!a){const e=f();if(e){t=e;a=true}}s=true;return a}function d(){return c(()=>({navigate:()=>console.warn("[route-events] @react-navigation/native not installed: navigate() unavailable"),goBack:()=>console.warn("[route-events] @react-navigation/native not installed: goBack() unavailable"),canGoBack:()=>false,reset:()=>console.warn("[route-events] @react-navigation/native not installed: reset() unavailable"),setParams:()=>console.warn("[route-events] @react-navigation/native not installed: setParams() unavailable"),dispatch:()=>console.warn("[route-events] @react-navigation/native not installed: dispatch() unavailable"),isFocused:()=>true,addListener:()=>()=>{},removeListener:()=>{},getParent:()=>void 0,getState:()=>void 0,getId:()=>void 0}),[])}function g(e){return c(()=>{const n={key:"default",index:0,routeNames:[],routes:[],type:"stack"};try{return e?e(n):n}catch{return n}},[e])}export function useSafeNavigation(){if(!i()){return d()}try{return t.useNavigation()}catch(e){console.warn("[route-events] Failed to use @react-navigation/native.useNavigation:",e);return d()}}export function useSafeNavigationState(e){if(!i()){return g(e)}try{return t.useNavigationState(e)}catch(n){console.warn("[route-events] Failed to use @react-navigation/native.useNavigationState:",n);return g(e)}}const C=p(void 0);export function getCommonActions(){return i()?t.CommonActions:null}export function getStackActions(){return i()?t.StackActions:null}let r=null;let u=null;function m(){if(r==null){r=i()&&t.NavigationContainerRefContext?t.NavigationContainerRefContext:C}if(u==null){const e=f();u=e?.NavigationContainerRefContext??C}return[r,u]}export function useSafeNavigationContainerRef(){const[e,n]=m();const x=l(e);const N=l(n);return x??N}export function isReactNavigationAvailable(){return i()}
|
|
@@ -1,27 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
import { browserRouter } from '@buoy-gg/shared-ui/utils';
|
|
4
|
-
export function useSafeNavigation() {
|
|
5
|
-
return browserRouter;
|
|
6
|
-
}
|
|
7
|
-
export function useSafeNavigationState(selector) {
|
|
8
|
-
return selector({
|
|
9
|
-
routes: [],
|
|
10
|
-
routeNames: [],
|
|
11
|
-
index: 0,
|
|
12
|
-
key: 'browser',
|
|
13
|
-
type: 'stack'
|
|
14
|
-
});
|
|
15
|
-
}
|
|
16
|
-
export function useSafeNavigationContainerRef() {
|
|
17
|
-
return undefined;
|
|
18
|
-
}
|
|
19
|
-
export function getCommonActions() {
|
|
20
|
-
return null;
|
|
21
|
-
}
|
|
22
|
-
export function getStackActions() {
|
|
23
|
-
return null;
|
|
24
|
-
}
|
|
25
|
-
export function isReactNavigationAvailable() {
|
|
26
|
-
return false;
|
|
27
|
-
}
|
|
1
|
+
"use strict";import{browserRouter as e}from"@buoy-gg/shared-ui/utils";export function useSafeNavigation(){return e}export function useSafeNavigationState(t){return t({routes:[],routeNames:[],index:0,key:"browser",type:"stack"})}export function useSafeNavigationContainerRef(){return void 0}export function getCommonActions(){return null}export function getStackActions(){return null}export function isReactNavigationAvailable(){return false}
|
|
@@ -1,55 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Stable e2e handles for the routes tool.
|
|
5
|
-
*
|
|
6
|
-
* Everything in this tool is addressed by its PATH, never by a list index or a
|
|
7
|
-
* per-session id. Route events are a prepend-list whose indices shift on every
|
|
8
|
-
* navigation, the sitemap re-sorts and regroups as you search, and the stack
|
|
9
|
-
* renumbers itself on every push — the pathname is the one thing that means the
|
|
10
|
-
* same screen on the next launch, and the only thing a test can name up front.
|
|
11
|
-
*
|
|
12
|
-
* A pathname is not testID-safe as it stands (`/blog/2024/react-native-tips`,
|
|
13
|
-
* `/pokemon/[id]`), so it is slugged the way the rest of Buoy's handles read:
|
|
14
|
-
* `buoy-routes-route-blog-year-slug`.
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
/** Any path-ish string → a testID-safe slug (`/` → `-`, brackets dropped). */
|
|
18
|
-
export function pathSlug(path) {
|
|
19
|
-
return String(path).toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "root";
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* `buoy-routes-event-row-<slug>-<visit>` for one row of the events timeline.
|
|
24
|
-
*
|
|
25
|
-
* The visit number is part of the handle because revisiting a screen is the
|
|
26
|
-
* normal case here: three trips to `/about` would otherwise be three views
|
|
27
|
-
* sharing one testID, which Detox reports as "multiple elements found" — an
|
|
28
|
-
* ambiguity error where the test meant "the second visit". It also makes the
|
|
29
|
-
* tool's own visit counting addressable rather than merely visible.
|
|
30
|
-
*/
|
|
31
|
-
export function eventRowTestID(pathname, visitNumber) {
|
|
32
|
-
return `buoy-routes-event-row-${pathSlug(pathname)}-${visitNumber}`;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/** `buoy-routes-route-<slug>` for one row of the sitemap. */
|
|
36
|
-
export function sitemapRouteTestID(path) {
|
|
37
|
-
return `buoy-routes-route-${pathSlug(path)}`;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/** `buoy-routes-group-<slug>` for a sitemap group header. */
|
|
41
|
-
export function sitemapGroupTestID(title) {
|
|
42
|
-
return `buoy-routes-group-${pathSlug(title)}`;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* `buoy-routes-stack-item-<index>` for one frame of the navigation stack.
|
|
47
|
-
*
|
|
48
|
-
* The exception to addressing by path: a stack legitimately holds the same
|
|
49
|
-
* route twice (push `/route-bench/1` from `/route-bench/1`), and its whole
|
|
50
|
-
* subject is POSITION — "index 2 of 4" is what the row means, so the position
|
|
51
|
-
* is what the handle should say.
|
|
52
|
-
*/
|
|
53
|
-
export function stackItemTestID(index) {
|
|
54
|
-
return `buoy-routes-stack-item-${index}`;
|
|
55
|
-
}
|
|
1
|
+
"use strict";export function pathSlug(t){return String(t).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"root"}export function eventRowTestID(t,e){return`buoy-routes-event-row-${pathSlug(t)}-${e}`}export function sitemapRouteTestID(t){return`buoy-routes-route-${pathSlug(t)}`}export function sitemapGroupTestID(t){return`buoy-routes-group-${pathSlug(t)}`}export function stackItemTestID(t){return`buoy-routes-stack-item-${t}`}
|
package/lib/web/index.mjs
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
var Ut=Object.defineProperty;var Vo=Object.getOwnPropertyDescriptor;var No=Object.getOwnPropertyNames;var Lo=Object.prototype.hasOwnProperty;var Ao=(e,t)=>{for(var o in t)Ut(e,o,{get:t[o],enumerable:!0})},Ht=(e,t,o,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of No(t))!Lo.call(e,r)&&r!==o&&Ut(e,r,{get:()=>t[r],enumerable:!(n=Vo(t,r))||n.enumerable});return e},O=(e,t,o)=>(Ht(e,t,"default"),o&&Ht(o,t,"default"));typeof window<"u"&&typeof globalThis.global>"u"&&(globalThis.global=globalThis);import{RoutesIcon as ta}from"@buoy-gg/floating-tools-core/web";import{useState as Fe,useCallback as ve,useEffect as mo,useRef as Vr,useMemo as We}from"react";var C={};Ao(C,{AccessibilityInfo:()=>Jo,ActivityIndicator:()=>Uo,Alert:()=>j,Animated:()=>Qo,AppRegistry:()=>Yo,AppState:()=>Zo,Appearance:()=>qo,BackHandler:()=>Xo,Button:()=>jo,CheckBox:()=>gn,Clipboard:()=>en,DeviceEventEmitter:()=>Pn,Dimensions:()=>tn,Easing:()=>on,FlatList:()=>bt,I18nManager:()=>nn,Image:()=>yn,ImageBackground:()=>hn,InteractionManager:()=>an,Keyboard:()=>rn,KeyboardAvoidingView:()=>bn,LayoutAnimation:()=>sn,Linking:()=>ln,LogBox:()=>Dn,Modal:()=>Mo,NativeEventEmitter:()=>un,NativeModules:()=>Ko,PanResponder:()=>cn,Picker:()=>vn,PixelRatio:()=>pn,Platform:()=>ht,Pressable:()=>zo,ProgressBar:()=>Rn,RefreshControl:()=>xn,SafeAreaView:()=>Sn,ScrollView:()=>Ie,SectionList:()=>Tn,Share:()=>dn,StatusBar:()=>wn,StyleSheet:()=>X,Switch:()=>Ho,Text:()=>p,TextInput:()=>yt,Touchable:()=>Cn,TouchableHighlight:()=>Oo,TouchableNativeFeedback:()=>In,TouchableOpacity:()=>W,TouchableWithoutFeedback:()=>$o,UIManager:()=>mn,Vibration:()=>fn,View:()=>s,VirtualizedList:()=>En,YellowBox:()=>kn,findNodeHandle:()=>Go,unstable_createElement:()=>_o,useColorScheme:()=>Bn,useLocaleContext:()=>Vn,useWindowDimensions:()=>Nn});O(C,Ea);import*as Ea from"react-native-web";import{unstable_createElement as _o,NativeModules as Ko,AccessibilityInfo as Jo,Animated as Qo,Appearance as qo,AppRegistry as Yo,AppState as Zo,BackHandler as Xo,Clipboard as en,Dimensions as tn,Easing as on,I18nManager as nn,Keyboard as rn,InteractionManager as an,LayoutAnimation as sn,Linking as ln,NativeEventEmitter as un,PanResponder as cn,PixelRatio as pn,Platform as ht,Share as dn,StyleSheet as X,UIManager as mn,Vibration as fn,CheckBox as gn,FlatList as bt,Image as yn,ImageBackground as hn,KeyboardAvoidingView as bn,Picker as vn,ProgressBar as Rn,RefreshControl as xn,SafeAreaView as Sn,SectionList as Tn,StatusBar as wn,Touchable as Cn,TouchableNativeFeedback as In,VirtualizedList as En,YellowBox as kn,LogBox as Dn,DeviceEventEmitter as Pn,useColorScheme as Bn,useLocaleContext as Vn,useWindowDimensions as Nn}from"react-native-web";import*as P from"react-native-web";import{createElement as Fo,forwardRef as Wo}from"react";function se(e){let t=Wo((n,r)=>{let{accessibilityState:a,accessibilityValue:l,...c}=n;for(let i of["busy","checked","disabled","expanded","selected"])a?.[i]!==void 0&&c[`aria-${i}`]===void 0&&(c[`aria-${i}`]=a[i]);for(let[i,m]of Object.entries({min:"valuemin",max:"valuemax",now:"valuenow",text:"valuetext"}))l?.[i]!==void 0&&c[`aria-${m}`]===void 0&&(c[`aria-${m}`]=l[i]);return Fo(e,{...c,ref:r})}),o=e.State;return o&&Object.assign(t,{State:o}),t.displayName=e.displayName??e.name??"NativeWebView",t}var s=se(P.View),p=se(P.Text),yt=se(P.TextInput),W=se(P.TouchableOpacity),Oo=se(P.TouchableHighlight),$o=se(P.TouchableWithoutFeedback),zo=se(P.Pressable),Ie=se(P.ScrollView),Mo=se(P.Modal),Ho=se(P.Switch),Uo=se(P.ActivityIndicator),jo=se(P.Button),Go=P.findNodeHandle,j={alert(e,t,o,n){if(typeof document>"u")return;let r=document.createElement("dialog");r.dataset.buoyRoot="",r.setAttribute("aria-label",e),r.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 a=document.createElement("h2");if(a.textContent=e,a.style.cssText="font-size:18px;margin:0 0 12px",r.appendChild(a),t){let m=document.createElement("p");m.textContent=t,m.style.cssText="line-height:1.5;white-space:pre-wrap;margin:0 0 20px",r.appendChild(m)}let l=document.createElement("div");l.style.cssText="display:flex;justify-content:flex-end;flex-wrap:wrap;gap:8px";let c=o?.length?o:[{text:"OK"}],i=()=>{r.close?.(),r.remove()};for(let m of c){let T=document.createElement("button");T.type="button",T.textContent=m.text??"OK",T.style.cssText=`padding:9px 14px;border:1px solid #64748b;border-radius:7px;color:white;background:${m.style==="destructive"?"#a52b38":"#283a4d"};cursor:pointer;font:inherit`,T.onclick=()=>{i(),m.onPress?.()},l.appendChild(T)}r.addEventListener("cancel",m=>{m.preventDefault(),n?.cancelable!==!1&&(i(),n?.onDismiss?.())}),r.appendChild(l),document.body.appendChild(r),r.showModal?r.showModal():r.setAttribute("open","")}};import{browserRouter as Pa}from"@buoy-gg/shared-ui/web/utils";function jt(){return null}import{useSafeRouter as Nr,isExpoRouterAvailable as Lr,windowDragProps as Ar,ToolEmptyState as Fr,resolveListEmptyState as Wr,usePersistedState as Vt,monoFont as ct}from"@buoy-gg/shared-ui/web";import{JsModal as Or,ModalHeader as fe,TabSelector as $r,formatRelativeTime as zr,devToolsStorageKeys as Qe,Trash2 as Mr,Filter as Hr,SearchBar as fo,ToolbarCopyButton as Nt,Lock as Ur,ProUpgradeModal as jr,PowerToggleButton as Gr,buoyColors as _r,night as Y,TickProvider as go,useLimit as Kr}from"@buoy-gg/shared-ui/web";import{useIsPro as Jr}from"@buoy-gg/license/web";import{useEventStoreEvents as Wn}from"@buoy-gg/shared-ui/web";import{BaseEventStore as Ln,devToolsStorageKeys as An,persistentStorage as Fn}from"@buoy-gg/shared-ui/web";var et=class{constructor(){this.listeners=new Set}emit(t){this.listeners.forEach(o=>{try{o(t)}catch(n){console.error("[RouteObserver] Error in listener:",n)}})}addListener(t){return this.listeners.add(t),()=>this.listeners.delete(t)}removeListener(t){this.listeners.delete(t)}},Se=new et;var vt=class extends Ln{constructor(){super({storeName:"route-events",maxEvents:500});this.routeObserverUnsubscribe=null;this.bootCaptureRelease=null;this.bootCaptureHydrated=!1}setBootCapture(o){o&&!this.bootCaptureRelease?this.bootCaptureRelease=this.subscribeToEvents(()=>{}):!o&&this.bootCaptureRelease&&(this.bootCaptureRelease(),this.bootCaptureRelease=null)}hydrateBootCapture(){this.bootCaptureHydrated||(this.bootCaptureHydrated=!0,Fn.getItem(An.routeEvents.isMonitoring()).then(o=>{this.bootCaptureRelease||this.setBootCapture(o!=="false")}).catch(()=>this.setBootCapture(!0)))}startCapturing(){this.routeObserverUnsubscribe||(this.routeObserverUnsubscribe=Se.addListener(o=>{this.addEvent(o)}))}stopCapturing(){this.routeObserverUnsubscribe&&(this.routeObserverUnsubscribe(),this.routeObserverUnsubscribe=null)}isCapturing(){return this.routeObserverUnsubscribe!==null}isListening(){return this.isCapturing()}},ne=new vt;function Rt(e={}){let{maxEvents:t=500,enabled:o=!0}=e,{events:n,clearEvents:r,isActive:a}=Wn(ne,{maxEvents:t,enabled:o});return{events:n,clearEvents:r,isListening:a}}import{Navigation as zn,night as ot,monoFont as Mn}from"@buoy-gg/shared-ui/web";import{InlineCopyButton as ze,night as xt,monoFont as St}from"@buoy-gg/shared-ui/web";import{DataViewer as On}from"@buoy-gg/shared-ui/web/dataViewer";import{jsx as M,jsxs as ee}from"react/jsx-runtime";function $n(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 Me({event:e,visitNumber:t,routeTemplate:o}){let n=e.params&&Object.keys(e.params).length>0;return ee(s,{style:R.container,children:[ee(s,{style:R.section,children:[o&&ee(s,{style:R.detailRow,testID:"buoy-routes-detail-template",children:[M(p,{style:R.detailLabel,children:"Template:"}),M(p,{style:R.detailValue,testID:"buoy-routes-detail-template-value",children:o}),M(ze,{value:o,buttonStyle:R.copyButton})]}),e.previousPathname&&ee(s,{style:R.detailRow,testID:"buoy-routes-detail-from",children:[M(p,{style:R.detailLabel,children:"From:"}),M(p,{style:R.detailValue,testID:"buoy-routes-detail-from-value",children:e.previousPathname}),M(ze,{value:e.previousPathname,buttonStyle:R.copyButton})]}),ee(s,{style:R.detailRow,testID:"buoy-routes-detail-to",children:[M(p,{style:R.detailLabel,children:"To:"}),M(p,{style:R.detailValue,testID:"buoy-routes-detail-to-value",children:e.pathname}),M(ze,{value:e.pathname,buttonStyle:R.copyButton})]})]}),ee(s,{style:R.section,children:[e.timeSincePrevious!==void 0&&ee(s,{style:R.detailRow,testID:"buoy-routes-detail-duration",children:[M(p,{style:R.detailLabel,children:"Duration:"}),M(p,{style:R.detailValue,testID:"buoy-routes-detail-duration-value",children:$n(e.timeSincePrevious)})]}),ee(s,{style:R.detailRow,testID:"buoy-routes-detail-time",children:[M(p,{style:R.detailLabel,children:"Time:"}),M(p,{style:R.detailValue,testID:"buoy-routes-detail-time-value",children:new Date(e.timestamp).toLocaleString()})]})]}),ee(s,{style:R.section,children:[e.segments&&e.segments.length>0&&ee(s,{style:R.detailRow,testID:"buoy-routes-detail-segments",children:[M(p,{style:R.detailLabel,children:"Segments:"}),M(p,{style:R.detailValue,testID:"buoy-routes-detail-segments-value",children:e.segments.join(" \u2192 ")}),M(ze,{value:JSON.stringify(e.segments),buttonStyle:R.copyButton})]}),n&&ee(s,{style:R.dataViewerContainer,children:[ee(s,{style:R.dataViewerHeader,children:[ee(p,{style:R.dataViewerTitle,testID:"buoy-routes-detail-params-title",children:["Parameters (",Object.keys(e.params).length,")"]}),M(ze,{value:JSON.stringify(e.params,null,2),buttonStyle:R.copyButton})]}),M(On,{data:e.params,title:"",showTypeFilter:!0,rawMode:!0,initialExpanded:!0})]}),t>1&&ee(s,{style:R.detailRow,testID:"buoy-routes-detail-visited",children:[M(p,{style:R.detailLabel,children:"Visited:"}),ee(p,{style:R.detailValue,testID:"buoy-routes-detail-visited-value",children:[t," time",t!==1?"s":""]})]})]})]})}var R=X.create({container:{gap:12},section:{gap:8},detailRow:{flexDirection:"row",alignItems:"center",gap:8},detailLabel:{fontSize:10,color:xt.color.textSecondary,fontFamily:St,fontWeight:"600",minWidth:70},detailValue:{fontSize:11,color:xt.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:xt.color.textSecondary,fontFamily:St,fontWeight:"600"}});function He(e,t){if(!t||t.length===0)return null;let n="/"+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 n!==e?n:null}function tt(e,t){if(!t)return e;let o=new Set(e.split("/").filter(Boolean).map(r=>{try{return decodeURIComponent(r)}catch{return r}})),n=[];for(let[r,a]of Object.entries(t)){let l=Array.isArray(a)?a:[a];if(!(l.length>0&&l.every(c=>o.has(String(c)))))for(let c of l)n.push(`${encodeURIComponent(r)}=${encodeURIComponent(String(c))}`)}return n.length?`${e}?${n.join("&")}`:e}function Gt(e){let t=e.indexOf("?");if(t<0)return{pathname:e,params:{}};let o={};for(let n of e.slice(t+1).split("&")){if(!n)continue;let[r,a=""]=n.split("=");try{o[decodeURIComponent(r)]=decodeURIComponent(a)}catch{o[r]=a}}return{pathname:e.slice(0,t),params:o}}import{jsx as Ue,jsxs as _t}from"react/jsx-runtime";function Tt({event:e,visitNumber:t=1,onNavigate:o}){let n=He(e.pathname,e.segments);return _t(s,{style:Be.container,children:[Ue(Ie,{testID:"buoy-routes-detail-scroll",style:Be.scroll,contentContainerStyle:Be.scrollContent,showsVerticalScrollIndicator:!0,children:Ue(Me,{event:e,visitNumber:t,routeTemplate:n})}),o&&Ue(s,{style:Be.footer,children:_t(W,{style:Be.goButton,onPress:()=>o(tt(e.pathname,e.params)),activeOpacity:.8,testID:"buoy-routes-detail-go",accessibilityRole:"button",accessibilityLabel:`Go to route ${e.pathname}`,children:[Ue(zn,{size:16,color:ot.color.onAccent}),Ue(p,{style:Be.goButtonText,children:"Go to route"})]})})]})}var Be=X.create({container:{flex:1,backgroundColor:"transparent"},scroll:{flex:1},scrollContent:{padding:14},footer:{paddingHorizontal:16,paddingVertical:12,backgroundColor:"transparent",borderTopWidth:1,borderTopColor:ot.color.border},goButton:{flexDirection:"row",alignItems:"center",justifyContent:"center",gap:8,backgroundColor:ot.color.accent,paddingVertical:12,borderRadius:8},goButtonText:{fontSize:13,fontWeight:"600",color:ot.color.onAccent,fontFamily:Mn,textTransform:"uppercase",letterSpacing:.5}});import{Filter as Kt,DynamicFilterView as Hn}from"@buoy-gg/shared-ui/web";import{jsx as Un}from"react/jsx-runtime";function Jt({ignoredPatterns:e,onTogglePattern:t,onAddPattern:o,availablePathnames:n=[]}){return Un(Hn,{...{addFilterSection:{enabled:!0,placeholder:"Enter pattern (e.g., /_sitemap)",title:"ACTIVE FILTERS",icon:Kt},availableItemsSection:{enabled:!0,title:"AVAILABLE ROUTES FROM EVENTS",emptyMessage:"No routes available. Routes from navigation events will appear here.",items:n},howItWorksSection:{enabled:!0,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:Kt},onPatternToggle:t,onPatternAdd:o,activePatterns:e}})}import{useState as Le,useCallback as _e,useMemo as rt,useEffect as qn}from"react";import{night as y,ToolEmptyState as Yn,monoFont as q}from"@buoy-gg/shared-ui/web";import{useSafeRouter as Zn}from"@buoy-gg/shared-ui/web";import{Search as to,ChevronDown as oo,ChevronRight as no,Home as Xn,InlineCopyButton as er,CopyButton as tr,RefreshCw as or,formatRelativeTime as nr,ProUpgradeModal as rr}from"@buoy-gg/shared-ui/web";import{useIsPro as ar}from"@buoy-gg/license/web";import{useState as _n,useEffect as Yt,useMemo as ke,useCallback as Kn}from"react";var re=class{static parseRouteTree(t){if(!t)return[];let o=[];return this.traverseNode(t,"",o,0),o}static traverseNode(t,o,n,r){let a=this.buildPath(t,o),l=this.detectRouteType(t),c=this.shouldIncludeRoute(t),i={path:a,name:t.route,type:l,params:this.extractParams(t),nodeType:t.type,contextKey:t.contextKey,isInternal:t.internal??!1,children:[],depth:r};c&&n.push(i);for(let m of t.children)this.traverseNode(m,a,c?i.children:n,r+1)}static buildPath(t,o){if(t.type==="layout"&&t.route==="_layout"||t.route.startsWith("(")&&t.route.endsWith(")"))return o;if(t.route==="index")return o||"/";let n=t.route;return!o||o==="/"?`/${n}`:`${o}/${n}`}static detectRouteType(t){let o=t.route;return t.dynamic?.some(n=>n.notFound)?"not-found":t.dynamic?.some(n=>n.deep)?"catch-all":t.dynamic&&t.dynamic.length>0?"dynamic":t.type==="layout"?"layout":o.startsWith("(")&&o.endsWith(")")?"group":o==="index"?"index":"static"}static extractParams(t){return!t.dynamic||t.dynamic.length===0?[]:t.dynamic.map(o=>o.name)}static shouldIncludeRoute(t){return!(t.internal||t.generated||t.type==="api")}static organizeRoutes(t){let o=[],n=this.flattenRoutes(t).filter(c=>c.type==="static"||c.type==="index"),r=this.flattenRoutes(t).filter(c=>c.type==="dynamic"||c.type==="catch-all"),a=this.flattenRoutes(t).filter(c=>c.type==="layout"),l=this.flattenRoutes(t).filter(c=>c.type==="group");return n.length>0&&o.push({title:"Static Routes",icon:"",routes:n}),r.length>0&&o.push({title:"Dynamic Routes",icon:"",description:"Routes that accept parameters",routes:r}),a.length>0&&o.push({title:"Layouts",icon:"",description:"Shared UI for nested screens",routes:a}),l.length>0&&o.push({title:"Route Groups",icon:"",routes:l}),o}static flattenRoutes(t){let o=[];function n(r){o.push(r),r.children.forEach(n)}return t.forEach(n),o}static getRouteStats(t){let o=this.flattenRoutes(t);return{total:o.length,static:o.filter(n=>n.type==="static").length,dynamic:o.filter(n=>n.type==="dynamic").length,catchAll:o.filter(n=>n.type==="catch-all").length,layouts:o.filter(n=>n.type==="layout").length,groups:o.filter(n=>n.type==="group").length}}static filterRoutes(t,o){if(!o)return t;let n=o.toLowerCase();return this.flattenRoutes(t).filter(a=>a.path.toLowerCase().includes(n)||a.name.toLowerCase().includes(n)||a.type.toLowerCase().includes(n)||a.params.some(l=>l.toLowerCase().includes(n)))}static buildTreeString(t,o=0){let n="";return t.forEach((r,a)=>{let l=a===t.length-1,i=`${this.buildTreePrefix(o,l)}${r.path}`;r.params.length>0&&(i+=` { ${r.params.join(", ")} }`),n+=i+`
|
|
3
|
-
`,r.children.length>0&&(n+=this.buildTreeString(r.children,o+1))}),n}static buildTreePrefix(t,o){return t===0?"":" ".repeat(t-1)+(o?"\u2514\u2500 ":"\u251C\u2500 ")}static sortRoutes(t,o="path"){let n=[...t];return n.sort((r,a)=>{switch(o){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}}),n}static findRouteByPath(t,o){return this.flattenRoutes(t).find(r=>r.path===o)||null}static getParentRoutes(t,o){let n=[],r=this.flattenRoutes(t);if(!r.find(i=>i.path===o))return n;let l=o.split("/").filter(Boolean),c="";for(let i=0;i<l.length-1;i++){c+="/"+l[i];let m=r.find(T=>T.path===c);m&&n.push(m)}return n}};import{getBrowserHref as Gn}from"@buoy-gg/shared-ui/web/utils";var Ve=new Map,wt=null;function jn(e){for(let o of e)Ve.set(o,(Ve.get(o)??0)+1);wt=Date.now();let t=!0;return()=>{if(t){t=!1;for(let o of e){let n=(Ve.get(o)??1)-1;n?Ve.set(o,n):Ve.delete(o)}wt=Date.now()}}}function Qt(){return[...Ve.keys()]}function qt(){return wt}function nt(){return typeof window<"u"}function Ee(){return nt()?{route:"",type:"layout",contextKey:"browser",children:[...new Set([...Qt(),new URL(Gn()).pathname])].map(t=>({route:t.replace(/^\//,"")||"index",type:"route",contextKey:t,children:[],dynamic:null}))}:null}function je(){return{source:null,lastLoadedAt:qt()}}function Ge(e={}){let{searchQuery:t="",sortBy:o="path",autoRefresh:n=!1,refreshInterval:r=1e3,injectedRoutes:a,injectedSource:l=null,injectedLastUpdatedAt:c=null}=e,i=a!=null,[m,T]=_n(()=>{let L=Ee(),A=je();return{node:L,version:0,lastUpdatedAt:A.lastLoadedAt,source:A.source}}),v=m.node,k=m.version,B=m.lastUpdatedAt,ce=m.source,J=Kn(()=>{T(L=>{let A=Ee(),ie=je();return{node:A,version:L.version+1,lastUpdatedAt:ie.lastLoadedAt,source:ie.source}})},[]);Yt(()=>{if(v||i||!nt())return;let L=0,A=100,ie=()=>{L++,J(),L<A&&(pe=setTimeout(ie,100))},pe=setTimeout(ie,100);return()=>clearTimeout(pe)},[v,J,i]),Yt(()=>{if(!n)return;let L=setInterval(J,r);return()=>clearInterval(L)},[n,r,J]);let z=i?a.length>0:!!v,N=i?!0:nt(),D=ke(()=>i?a:v?re.parseRouteTree(v):[],[v,k,i,a]),ae=ke(()=>re.sortRoutes(D,o),[D,o]),I=ke(()=>t?re.filterRoutes(ae,t):ae,[ae,t]),Z=ke(()=>re.organizeRoutes(I),[I]),Re=ke(()=>re.getRouteStats(D),[D]);return{routes:ae,groups:Z,stats:Re,filteredRoutes:I,isLoaded:z,isSupported:N,refresh:J,findRoute:L=>re.findRouteByPath(D,L),getParents:L=>re.getParentRoutes(D,L),lastUpdatedAt:i?c:B,source:i?l:ce}}function Jn(e){let{findRoute:t}=Ge();return ke(()=>t(e),[t,e])}function Qn(e){let{getParents:t}=Ge();return ke(()=>t(e),[t,e])}function Ct(e){return String(e).toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"root"}function Zt(e,t){return`buoy-routes-event-row-${Ct(e)}-${t}`}function Xt(e){return`buoy-routes-route-${Ct(e)}`}function It(e){return`buoy-routes-group-${Ct(e)}`}function eo(e){return`buoy-routes-stack-item-${e}`}import{jsx as d,jsxs as $}from"react/jsx-runtime";var te=ht.OS==="web",at=te?22:16,ir={path:"/",name:"index",type:"index",params:[],nodeType:"route",contextKey:"/",isInternal:!1,children:[],depth:0};function Ae({style:e,injectedRoutes:t,injectedSource:o,injectedLastUpdatedAt:n,onNavigateRoute:r}){let[a,l]=Le(""),[c,i]=Le(!1),[m,T]=Le(new Set(["Static Routes","Dynamic Routes"])),[v,k]=Le(!1),[B,ce]=Le(!1),J=ar();qn(()=>{B&&J&&ce(!1)},[B,J]);let z=Zn(),{groups:N,stats:D,isLoaded:ae,isSupported:I,filteredRoutes:Z,routes:Re,refresh:H,lastUpdatedAt:ge,source:L}=Ge({searchQuery:a,sortBy:"path",injectedRoutes:t,injectedSource:o,injectedLastUpdatedAt:n}),A=rt(()=>({summary:{total:D.total,static:D.static,dynamic:D.dynamic,layouts:D.layouts,groups:D.groups,timestamp:new Date().toISOString()},groups:N.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:Re.map(b=>b.path)}),[N,D,Re]),ie=_e(b=>{T(w=>{let oe=new Set(w);return oe.has(b)?oe.delete(b):oe.add(b),oe})},[]),pe=_e((b,w=0,oe={})=>{let Oe=b.params;if(w>=Oe.length){let de=b.path;Object.entries(oe).forEach(([Te,Ye])=>{b.type==="catch-all"?de=de.replace(`[...${Te}]`,Ye):de=de.replace(`[${Te}]`,Ye)});try{z.push(de)}catch(Te){j.alert("Navigation Error",String(Te))}return}let $e=Oe[w],dt=b.type==="catch-all"?`[...${$e}]`:`[${$e}]`;j.prompt("Enter Parameter Value",`Enter value for ${dt}:
|
|
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(i=>i.path===t))return o;let a=t.split("/").filter(Boolean),n="";for(let i=0;i<a.length-1;i++){n+="/"+a[i];let u=r.find(c=>c.path===n);u&&o.push(u)}return o}};import{getBrowserHref as da}from"@buoy-gg/shared-ui/web/utils";var De=new Map,ut=null;function pa(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 ma(){return[...De.keys()]}function ha(){return ut}function dt(){return typeof window<"u"}function We(){return dt()?{route:"",type:"layout",contextKey:"browser",children:[...new Set([...ma(),new URL(da()).pathname])].map(e=>({route:e.replace(/^\//,"")||"index",type:"route",contextKey:e,children:[],dynamic:null}))}:null}function pt(){return{source:null,lastLoadedAt:ha()}}function Je(e={}){let{searchQuery:t="",sortBy:o="path",autoRefresh:r=false,refreshInterval:a=1e3,injectedRoutes:n,injectedSource:i=null,injectedLastUpdatedAt:u=null}=e,c=n!=null,[h,I]=ca(()=>{let R=We(),V=pt();return{node:R,version:0,lastUpdatedAt:V.lastLoadedAt,source:V.source}}),v=h.node,T=h.version,$=h.lastUpdatedAt,ae=h.source,O=ua(()=>{I(R=>{let V=We(),K=pt();return{node:V,version:R.version+1,lastUpdatedAt:K.lastLoadedAt,source:K.source}})},[]);Ut(()=>{if(v||c||!dt())return;let R=0,V=100,K=()=>{R++,O(),R<V&&(z=setTimeout(K,100))},z=setTimeout(K,100);return()=>clearTimeout(z)},[v,O,c]),Ut(()=>{if(!r)return;let R=setInterval(O,a);return()=>clearInterval(R)},[r,a,O]);let N=c?n.length>0:!!v,P=c?true:dt(),D=Se(()=>c?n:v?ge.parseRouteTree(v):[],[v,T,c,n]),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:O,findRoute:R=>ge.findRouteByPath(D,R),getParents:R=>ge.getParentRoutes(D,R),lastUpdatedAt:c?u:$,source:c?i:ae}}function ga(e){let{findRoute:t}=Je();return Se(()=>t(e),[t,e])}function ya(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 fa(e,t){return`buoy-routes-event-row-${mt(e)}-${t}`}function ba(e){return`buoy-routes-route-${mt(e)}`}function Gt(e){return`buoy-routes-group-${mt(e)}`}function va(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,xa={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[n,i]=Be(""),[u,c]=Be(false),[h,I]=Be(new Set(["Static Routes","Dynamic Routes"])),[v,T]=Be(false),[$,ae]=Be(false),O=la();Yr(()=>{$&&O&&ae(false)},[$,O]);let N=ta(),{groups:P,stats:D,isLoaded:ee,isSupported:k,filteredRoutes:G,routes:pe,refresh:R,lastUpdatedAt:V,source:K}=Je({searchQuery:n,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}:
|
|
4
3
|
|
|
5
|
-
Route: ${b.path}`,[{text:"Cancel",style:"cancel"},{text:w<Oe.length-1?"Next":"Navigate",onPress:de=>{if(de&&de.trim()){let Te={...oe,[$e]:de.trim()};pe(b,w+1,Te)}else j.alert("Invalid Value","Please enter a value for the parameter")}}],"plain-text")},[z]),Ce=_e((b,w)=>{if(r){r(b);return}if(!J&&!w?.bypassPro){ce(!0);return}if(b.type==="layout"||b.type==="group"){j.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{z.push(b.path)}catch(oe){j.alert("Navigation Error",String(oe))}return}pe(b);return}try{z.push(b.path)}catch(oe){j.alert("Navigation Error",String(oe))}},[z,pe,J,r]),ye=_e(()=>{Ce(ir,{bypassPro:!0})},[Ce]),h=_e(()=>{v||(k(!0),H(),setTimeout(()=>k(!1),400))},[v,H]),V=rt(()=>ge?`Updated ${nr(ge)}`:"Awaiting route data",[ge]),Q=rt(()=>L?`Source: ${L}`:"Source: unknown",[L]),he=rt(()=>a&&Z.length>0?[{title:"Search Results",icon:"",routes:Z}]:N,[a,Z,N]);return ae?$(s,{style:[u.container,e],children:[c&&$(s,{style:u.searchContainer,testID:"buoy-routes-sitemap-search-field",children:[d(to,{size:16,color:y.color.textTertiary}),d(yt,{style:u.searchInput,placeholder:"Search routes...",placeholderTextColor:y.color.placeholder,value:a,onChangeText:l,autoCapitalize:"none",autoCorrect:!1,autoFocus:!0,testID:"buoy-routes-sitemap-search",accessibilityLabel:"Search routes"}),a.length>0&&d(W,{onPress:()=>l(""),style:u.clearButton,testID:"buoy-routes-sitemap-search-clear",accessibilityRole:"button",accessibilityLabel:"Clear route search",children:d(p,{style:u.clearButtonText,children:"\u2715"})}),d(W,{style:u.closeSearchButton,onPress:()=>{i(!1),l("")},testID:"buoy-routes-sitemap-search-done",accessibilityRole:"button",accessibilityLabel:"Done searching routes",children:d(p,{style:u.closeSearchText,children:"Done"})})]}),$(Ie,{testID:"buoy-routes-sitemap-scroll",style:u.scrollView,contentContainerStyle:u.scrollContent,children:[!c&&$(s,{style:u.header,children:[$(s,{style:u.actionsRow,children:[$(s,{style:[u.actionWrapper,te&&u.actionWrapperDesktop],children:[d(W,{style:[u.iconButton,te&&u.iconButtonDesktop],onPress:ye,accessibilityLabel:"Go to home route",accessibilityRole:"button",testID:"buoy-routes-sitemap-home",children:d(Xn,{size:at,color:y.color.textSecondary})}),d(p,{style:[u.actionLabel,te&&u.actionLabelDesktop],children:"Home"})]}),$(s,{style:[u.actionWrapper,te&&u.actionWrapperDesktop],children:[d(tr,{value:A,testID:"buoy-routes-sitemap-copy",size:te?at:14,buttonStyle:te?u.actionButtonHeaderDesktop:u.actionButtonHeader}),d(p,{style:[u.actionLabel,te&&u.actionLabelDesktop],children:"Copy"})]}),$(s,{style:[u.actionWrapper,te&&u.actionWrapperDesktop],children:[d(W,{style:[u.iconButton,te&&u.iconButtonDesktop,v&&u.refreshButtonDisabled],onPress:h,disabled:v,testID:"buoy-routes-sitemap-refresh",accessibilityRole:"button",accessibilityLabel:"Refresh route tree",children:d(or,{size:at,color:v?y.color.textTertiary:y.color.textSecondary})}),d(p,{style:[u.actionLabel,te&&u.actionLabelDesktop],children:"Refresh"})]}),$(s,{style:[u.actionWrapper,te&&u.actionWrapperDesktop],children:[d(W,{style:[u.iconButton,te&&u.iconButtonDesktop],onPress:()=>i(!0),testID:"buoy-routes-sitemap-search-open",accessibilityRole:"button",accessibilityLabel:"Search routes",children:d(to,{size:at,color:y.color.textSecondary})}),d(p,{style:[u.actionLabel,te&&u.actionLabelDesktop],children:"Search"})]})]}),$(s,{style:u.statsGrid,children:[d(Ne,{value:D.total,label:"Total",id:"total"}),d(Ne,{value:D.static,label:"Static",id:"static"}),d(Ne,{value:D.dynamic,label:"Dynamic",id:"dynamic"}),d(Ne,{value:D.catchAll,label:"Catch-All",id:"catch-all"}),d(Ne,{value:D.layouts,label:"Layouts",id:"layouts"}),d(Ne,{value:D.groups,label:"Groups",id:"groups"})]})]}),he.length===0?d(Yn,{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."}):he.map(b=>d(sr,{group:b,isExpanded:a.length>0||m.has(b.title),onToggleExpand:()=>ie(b.title),onNavigate:Ce},b.title)),$(s,{style:u.metaFooter,children:[d(p,{style:u.metaText,testID:"buoy-routes-sitemap-updated",children:V}),d(s,{style:u.sourceBadge,children:d(p,{style:u.sourceText,testID:"buoy-routes-sitemap-source",children:Q})})]})]}),d(rr,{visible:B,onClose:()=>ce(!1),featureName:"Route Navigation"})]}):d(s,{style:[u.container,e],children:d(s,{style:u.loadingContainer,children:d(p,{style:u.loadingText,testID:"buoy-routes-sitemap-loading",children:I?"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 Ne({value:e,label:t,id:o}){return $(s,{style:u.statItem,testID:`buoy-routes-stat-${o}`,accessibilityLabel:`${t}, ${e}`,children:[d(p,{style:u.statValue,testID:`buoy-routes-stat-${o}-value`,children:e}),d(p,{style:u.statLabel,children:t})]})}function sr({group:e,isExpanded:t,onToggleExpand:o,onNavigate:n}){return $(s,{style:u.groupContainer,children:[$(W,{style:u.groupHeader,onPress:o,activeOpacity:.7,testID:It(e.title),accessibilityRole:"button",accessibilityLabel:`${e.title}, ${e.routes.length} routes`,children:[$(s,{style:u.groupHeaderLeft,children:[t?d(oo,{size:14,color:y.color.textSecondary}):d(no,{size:14,color:y.color.textSecondary}),d(p,{style:u.groupTitle,children:e.title})]}),d(s,{style:u.groupBadge,children:d(p,{style:u.groupCount,testID:`${It(e.title)}-count`,children:e.routes.length})})]}),e.description&&d(s,{style:u.groupDescription,children:d(p,{style:u.groupDescriptionText,children:e.description})}),t&&d(s,{style:u.routesList,children:e.routes.map((r,a)=>d(ro,{route:r,onNavigate:n},`${r.path}-${a}`))})]})}function ro({route:e,depth:t=0,onNavigate:o}){let[n,r]=Le(!1),a=e.children.length>0,l=lr(e.type),c=e.type!=="layout"&&e.type!=="group",i=Xt(e.path),m=a,T=m?n:!0;return d(s,{style:[u.routeItem,{marginLeft:t*12}],testID:i,children:$(s,{style:u.routeCard,children:[$(s,{style:u.routeHeader,children:[m?$(W,{style:u.routeHeaderLeft,onPress:()=>r(!n),activeOpacity:.7,testID:`${i}-toggle`,accessibilityRole:"button",accessibilityLabel:`${e.path}, ${e.type}, ${e.children.length} nested`,children:[d(s,{style:u.expandIndicator,children:n?d(oo,{size:14,color:y.color.textSecondary}):d(no,{size:14,color:y.color.textSecondary})}),d(p,{style:u.routePath,numberOfLines:3,testID:`${i}-path`,children:e.path})]}):$(s,{style:u.routeHeaderLeft,accessible:!0,accessibilityLabel:`${e.path}, ${e.type}`,children:[d(s,{style:u.expandIndicator}),d(p,{style:u.routePath,numberOfLines:3,testID:`${i}-path`,children:e.path})]}),$(s,{style:u.routeHeaderActions,children:[a&&d(s,{style:u.childCountBadge,children:d(p,{style:u.childCountText,testID:`${i}-children-count`,children:e.children.length})}),d(s,{style:[u.typeTag,{backgroundColor:`${l}15`,borderColor:`${l}40`}],children:d(p,{style:[u.typeText,{color:l}],testID:`${i}-type`,children:e.type.toUpperCase()})}),d(er,{value:e.path,buttonStyle:u.iconAction,testID:`${i}-copy`}),c&&d(W,{style:u.goButton,onPress:()=>o(e),activeOpacity:.7,testID:`${i}-go`,accessibilityRole:"button",accessibilityLabel:`Go to ${e.path}`,children:d(p,{style:u.goButtonText,children:"Go"})})]})]}),T&&a&&d(s,{style:u.childrenContainer,children:e.children.map((v,k)=>d(ro,{route:v,depth:t+1,onNavigate:o},`${v.path}-${k}`))})]})})}function lr(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 u=X.create({container:{flex:1,backgroundColor:"transparent"},loadingContainer:{flex:1,justifyContent:"center",alignItems:"center"},loadingText:{color:y.color.textSecondary,fontSize:14,fontFamily:q,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:q},statLabel:{fontSize:10,color:y.color.textTertiary,marginTop:4,fontFamily:q,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:q,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:q},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:q},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:q},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:q},scrollView:{flex:1},scrollContent:{paddingBottom:8},emptyState:{padding:32,alignItems:"center"},emptyText:{color:y.color.textSecondary,fontSize:14,fontFamily:q},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:q,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:q},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:q,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:q,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:q},typeTag:{borderRadius:4,paddingHorizontal:6,paddingVertical:2,borderWidth:1},typeText:{fontSize:10,fontWeight:"600",fontFamily:q},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:q,fontWeight:"600"},childrenContainer:{borderLeftWidth:2,borderLeftColor:y.color.border,marginLeft:16,marginRight:8,marginTop:2,marginBottom:8}});import{useState as ao,useMemo as it,useEffect as io}from"react";import{ChevronDown as pr,ChevronRight as dr,InlineCopyButton as mr,ProUpgradeModal as fr,buoyColors as st,night as K,useSafeAreaInsets as gr,ToolEmptyState as yr,monoFont as me}from"@buoy-gg/shared-ui/web";import{useIsPro as hr}from"@buoy-gg/license/web";import{DataViewer as br}from"@buoy-gg/shared-ui/web/dataViewer";import{useSyncExternalStore as ur}from"react";var Et=class{constructor(){this.stack=[];this.actions=null;this.listeners=new Set}getStack(){return this.stack}setStack(t){this.stack=t,this.listeners.forEach(o=>o())}getActions(){return this.actions}setActions(t){this.actions=t}subscribe(t){return this.listeners.add(t),()=>{this.listeners.delete(t)}}},G=new Et;var cr=[];function kt(){let e=ur(n=>G.subscribe(n),()=>G.getStack(),()=>cr),t=e.find(n=>n.isFocused)??null,o=()=>{let n=G.getActions();if(!n)throw new Error("Mount RouteTracker to capture browser navigation.");return n};return{stack:e,focusedRoute:t,stackDepth:e.length,isAtRoot:!t||t.index===0,isLoaded:e.length>0,error:null,refresh:()=>{},navigateToIndex:n=>o().navigateToIndex(n),navigateToRoute:(n,r)=>o().navigateToRoute?.(n,r)??!1,popToIndex:n=>o().popToIndex(n),goBack:()=>o().goBack(),popToTop:()=>o().popToTop()}}import{jsx as S,jsxs as le}from"react/jsx-runtime";function Dt({style:e,injectedStack:t,onAction:o,onCopyValueChange:n}){let r=kt(),a=t!=null,l=gr({minBottom:8}),c=a?t:r.stack,i=a?!0:r.isLoaded,m=a?null:r.error,T=it(()=>c.find(h=>h.isFocused)??null,[c]),v=c.length,k=v<=1,B=h=>o?o("navigateToIndex",{index:h}):r.navigateToIndex(h),ce=h=>o?o("popToIndex",{index:h}):r.popToIndex(h),J=()=>o?o("goBack"):r.goBack(),z=()=>o?o("popToTop"):r.popToTop(),[N,D]=ao(null),[ae,I]=ao(!1),Z=hr();io(()=>{ae&&Z&&I(!1)},[ae,Z]);let Re=it(()=>{let h=c.map(V=>({pathname:V.pathname,name:V.name,params:V.params,isFocused:V.isFocused}));return JSON.stringify(h,null,2)},[c]);io(()=>{n?.(Re)},[Re,n]);let H=it(()=>N!==null&&c[N]?c[N]:T,[N,c,T]),ge=it(()=>N!==null&&c[N]&&!c[N].isFocused,[N,c]);if(!i)return S(s,{style:[f.container,e],children:S(s,{style:f.loadingContainer,children:S(p,{style:f.loadingText,testID:"buoy-routes-stack-loading",children:"Loading navigation stack..."})})});if(m)return S(s,{style:[f.container,e],children:le(s,{style:f.errorContainer,testID:"buoy-routes-stack-error",children:[S(p,{style:f.errorText,children:"Error loading stack"}),S(p,{style:f.errorDetail,testID:"buoy-routes-stack-error-detail",children:m.message})]})});if(c.length===0)return S(s,{style:[f.container,e],children:S(yr,{testID:"buoy-routes-stack-empty",otto:"walking",title:"No navigation stack",message:"Navigate to a route to see the stack"})});let L=(h,V,Q,he)=>{if(o){let b=globalThis.window?.confirm;(!b||b(`${h}
|
|
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}
|
|
6
5
|
|
|
7
|
-
${V}`))&&he();return}j.alert(h,V,[{text:"Cancel",style:"cancel"},{text:Q,style:"destructive",onPress:he}])},A=()=>{if(!Z){I(!0);return}if(k){j.alert("Cannot Go Back","Already at the root of the stack");return}J()},ie=()=>{if(!Z){I(!0);return}if(k){j.alert("Already at Top","Stack only has one screen");return}L("Pop to Top","This will remove all screens except the root screen.","Pop to Top",z)},pe=h=>{D(N===h?null:h)},Ce=()=>{if(!Z){I(!0);return}if(H){if(H.isFocused){j.alert("Already There","This route is already visible");return}B(H.index)}},ye=()=>{if(!Z){I(!0);return}if(!H)return;if(H.isFocused){j.alert("Cannot Pop","Selected route is already visible");return}if(H.index===v-1){j.alert("Cannot Pop","No screens above selected route");return}let h=v-1-H.index,V=H.index;L("Pop to Route",`Remove ${h} screen${h!==1?"s":""} above ${H.pathname}?`,"Pop",()=>ce(V))};return le(s,{style:[f.container,e],children:[S(Ie,{testID:"buoy-routes-stack-scroll",style:f.stackScroll,contentContainerStyle:[f.stackContent,{paddingBottom:f.stackContent.padding+l.bottom}],children:[...c].reverse().map((h,V)=>{let Q=c.length-1-V,he=N===Q,b=Object.keys(h.params).length>0,w=eo(Q);return S(s,{style:f.stackItemWrapper,testID:w,children:le(s,{style:[f.stackItem,he&&f.stackItemSelected],children:[le(W,{style:f.stackItemHeader,onPress:()=>pe(Q),activeOpacity:.7,testID:`${w}-toggle`,accessibilityRole:"button",accessibilityLabel:`${h.pathname}, ${h.isFocused?"focused":"mounted"}, position ${Q} of ${v-1}`,children:[S(s,{style:f.expandIndicator,children:he?S(pr,{size:14,color:K.color.textSecondary}):S(dr,{size:14,color:K.color.textSecondary})}),S(p,{style:f.stackItemPath,numberOfLines:1,testID:`${w}-path`,children:h.pathname}),S(mr,{value:h.pathname,buttonStyle:f.copyRouteButton,testID:`${w}-copy`}),S(s,{style:[f.statusBadge,{backgroundColor:h.isFocused?`${st.success}15`:"#3B82F615",borderColor:h.isFocused?`${st.success}40`:"#3B82F640"}],children:S(p,{style:[f.statusBadgeText,{color:h.isFocused?st.success:"#3B82F6"}],testID:`${w}-status`,children:h.isFocused?"FOCUSED":"MOUNTED"})})]}),he&&le(s,{style:f.expandedContent,children:[le(s,{style:f.detailRow,children:[S(p,{style:f.detailLabel,children:"Route Name:"}),S(p,{style:f.detailValue,testID:`${w}-name`,children:h.name})]}),le(s,{style:f.detailRow,children:[S(p,{style:f.detailLabel,children:"Position:"}),le(p,{style:f.detailValue,testID:`${w}-position`,children:[Q," / ",v-1]})]}),b&&S(s,{style:f.dataViewerContainer,children:S(br,{title:"Parameters",data:h.params,showTypeFilter:!1})}),le(s,{style:f.actionsRow,children:[le(s,{style:f.actionWrapper,children:[S(W,{style:[f.actionButton,k&&f.actionButtonDisabled],onPress:A,disabled:k,testID:`${w}-back`,accessibilityRole:"button",accessibilityLabel:"Go back one screen",children:S(p,{style:[f.actionButtonText,k&&f.actionButtonTextDisabled],children:"Back"})}),S(p,{style:f.helpText,children:"Go back one screen"})]}),le(s,{style:f.actionWrapper,children:[S(W,{style:[f.actionButton,h.isFocused&&f.actionButtonDisabled],onPress:Ce,disabled:h.isFocused,testID:`${w}-go`,accessibilityRole:"button",accessibilityLabel:`Navigate to ${h.pathname}`,children:S(p,{style:[f.actionButtonText,h.isFocused&&f.actionButtonTextDisabled],children:"Go"})}),S(p,{style:f.helpText,children:"Navigate to this route"})]}),le(s,{style:f.actionWrapper,children:[S(W,{style:[f.actionButton,(h.isFocused||Q===v-1)&&f.actionButtonDisabled],onPress:ye,disabled:h.isFocused||Q===v-1,testID:`${w}-pop-to`,accessibilityRole:"button",accessibilityLabel:`Remove screens above ${h.pathname}`,children:S(p,{style:[f.actionButtonText,(h.isFocused||Q===v-1)&&f.actionButtonTextDisabled],children:"Pop To"})}),S(p,{style:f.helpText,children:"Remove screens above this"})]})]})]})]})},`stack-${Q}-${h.key}`)})}),S(fr,{visible:ae,onClose:()=>I(!1),featureName:"Stack Navigation"})]})}var f=X.create({container:{flex:1,backgroundColor:"transparent"},loadingContainer:{flex:1,justifyContent:"center",alignItems:"center",padding:32},loadingText:{color:K.color.textSecondary,fontSize:14,fontFamily:me},errorContainer:{flex:1,justifyContent:"center",alignItems:"center",padding:32},errorText:{color:st.error,fontSize:16,fontWeight:"600",fontFamily:me,marginBottom:8},errorDetail:{color:K.color.textSecondary,fontSize:12,fontFamily:me,textAlign:"center"},emptyContainer:{flex:1,justifyContent:"center",alignItems:"center",padding:32},emptyText:{color:K.color.text,fontSize:16,fontWeight:"600",fontFamily:me,marginBottom:8},emptySubtext:{color:K.color.textSecondary,fontSize:14,fontFamily:me,textAlign:"center"},stackScroll:{flex:1},stackContent:{padding:8},stackItemWrapper:{marginBottom:6},stackItem:{backgroundColor:K.color.surface,borderRadius:6,borderWidth:1,borderColor:K.color.border,overflow:"hidden"},stackItemSelected:{borderColor:K.color.accent,borderWidth:2},stackItemHeader:{flexDirection:"row",alignItems:"center",paddingVertical:10,paddingHorizontal:12,gap:8},expandIndicator:{width:20,alignItems:"center"},stackItemPath:{fontSize:13,fontWeight:"600",color:K.color.text,fontFamily:me,flex:1},copyRouteButton:{padding:4,marginLeft:4},statusBadge:{borderRadius:4,paddingHorizontal:6,paddingVertical:2,borderWidth:1},statusBadgeText:{fontSize:10,fontWeight:"600",fontFamily:me},expandedContent:{paddingHorizontal:12,paddingTop:8,paddingBottom:12,borderTopWidth:1,borderTopColor:K.color.border},detailRow:{marginBottom:8},detailLabel:{fontSize:10,color:K.color.textSecondary,fontFamily:me,marginBottom:2},detailValue:{fontSize:12,color:K.color.text,fontFamily:me},dataViewerContainer:{marginTop:4,marginHorizontal:-12,marginBottom:8},actionsRow:{flexDirection:"row",gap:6,marginTop:12},actionWrapper:{flex:1},actionButton:{backgroundColor:K.color.surfaceElevated,paddingVertical:8,paddingHorizontal:8,borderRadius:6,alignItems:"center"},actionButtonDisabled:{opacity:.5},actionButtonText:{fontSize:12,fontWeight:"600",color:K.color.text,fontFamily:me},actionButtonTextDisabled:{color:K.color.textTertiary},helpText:{fontSize:9,color:K.color.textSecondary,fontFamily:me,textAlign:"center",marginTop:4,lineHeight:12}});import{useCallback as kr}from"react";import{Navigation as Dr,night as Bt,EVENT_LIST_PRESET as Pr,monoFont as co}from"@buoy-gg/shared-ui/web";import{memo as vr,useMemo as be}from"react";import{CompactRow as Rr,RelativeTime as xr,buoyColors as so,night as lt,monoFont as lo}from"@buoy-gg/shared-ui/web";import{jsx as Ke}from"react/jsx-runtime";function Sr(e){return e.pathname==="/"?"home":He(e.pathname,e.segments)?"dynamic":e.params&&Object.keys(e.params).length>0?"with-params":"default"}function Tr(e){switch(e){case"home":return so.success;case"dynamic":return lt.color.accent;case"with-params":return so.warning;default:return lt.color.textSecondary}}function wr(e){switch(e){case"home":return"Home";case"dynamic":return"Dynamic";case"with-params":return"Params";default:return"Static"}}function Cr(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 Ir(e){let t=[];e.timeSincePrevious!==void 0&&e.timeSincePrevious>0&&t.push(Cr(e.timeSincePrevious));let o=e.segments?.length||0;return o>0&&t.push(`depth ${o}`),t.join(" \xB7 ")||"root"}function Er(e){if(e.params&&Object.keys(e.params).length>0){let o=Object.keys(e.params).length;return`${o} PARAM${o!==1?"S":""}`}}var Pt=vr(function({event:t,visitNumber:o,isExpanded:n,onPress:r,onNavigate:a,index:l}){let c=be(()=>Sr(t),[t]),i=be(()=>He(t.pathname,t.segments),[t.pathname,t.segments]),m=be(()=>Tr(c),[c]),T=be(()=>wr(c),[c]),v=be(()=>Ir(t),[t]),k=be(()=>Er(t),[t]),B=be(()=>Zt(t.pathname,o),[t.pathname,o]),ce=be(()=>`${t.pathname}, ${T}, ${v}`,[t.pathname,T,v]),J=be(()=>{if(n)return Ke(Me,{event:t,visitNumber:o,routeTemplate:i})},[n,t,o,i]),z=be(()=>{if(a)return Ke(W,{style:uo.goButton,onPress:()=>a(tt(t.pathname,t.params)),testID:`${B}-go`,accessibilityRole:"button",accessibilityLabel:`Go to ${t.pathname}`,children:Ke(p,{style:uo.goButtonText,children:"Go"})})},[a,t.pathname,B]);return Ke(Rr,{statusDotColor:m,statusLabel:T,statusSublabel:v,primaryText:t.pathname,badgeText:k,badgeColor:m,trailingAction:z,bottomRightText:Ke(xr,{timestamp:t.timestamp}),showChevron:!0,expandedContent:J,isExpanded:n,expandedGlowColor:m,onPress:()=>r(l),testID:B,statusTestID:`${B}-status`,statusSublabelTestID:`${B}-sublabel`,accessibilityLabel:ce})}),uo=X.create({badgeText:{fontSize:11,fontWeight:"600",fontFamily:lo},goButton:{backgroundColor:lt.color.accent,paddingHorizontal:8,paddingVertical:4,borderRadius:4},goButtonText:{fontSize:10,fontWeight:"600",color:lt.color.onAccent,fontFamily:lo}});import{jsx as Je,jsxs as Br}from"react/jsx-runtime";function po({events:e,visitCounts:t,onNavigate:o,onSelectEvent:n}){let r=kr(a=>{let l=e[a];l&&n(l,t.get(l)||1)},[e,t,n]);return e.length===0?Br(s,{style:ut.emptyState,testID:"buoy-routes-empty",children:[Je(Dr,{size:48,color:Bt.color.textTertiary}),Je(p,{style:ut.emptyTitle,testID:"buoy-routes-empty-title",children:"No events yet"}),Je(p,{style:ut.emptySubtitle,testID:"buoy-routes-empty-subtitle",children:"Navigation events will appear here"})]}):Je(bt,{testID:"buoy-routes-timeline",contentContainerStyle:ut.listContent,data:e,keyExtractor:a=>`${a.timestamp}-${a.pathname}`,renderItem:({item:a,index:l})=>Je(Pt,{event:a,visitNumber:t.get(a)||1,isExpanded:!1,index:l,onPress:r,onNavigate:o}),showsVerticalScrollIndicator:!0,...Pr})}var ut=X.create({listContent:{paddingVertical:8},emptyState:{flex:1,justifyContent:"center",alignItems:"center",padding:32},emptyTitle:{color:Bt.color.text,fontSize:16,fontWeight:"600",marginTop:16,marginBottom:8,fontFamily:co,letterSpacing:.5,textTransform:"uppercase"},emptySubtitle:{color:Bt.color.textSecondary,fontSize:14,textAlign:"center",fontFamily:co}});import{Fragment as ea,jsx as x,jsxs as ue}from"react/jsx-runtime";var Lt=jt(),Qr={parse:e=>e==="routes"||e==="events"||e==="stack"?e:void 0,serialize:e=>e},qr={parse:e=>e==="true",serialize:e=>e.toString()},Yr={parse:e=>new Set(JSON.parse(e)),serialize:e=>JSON.stringify(Array.from(e))};function yo(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 n=yo(o.state,t);if(n)return[o.name,...n]}}return null}function Zr(e,t){if(e.length===0)return null;let o=t&&Object.keys(t).length>0?t:void 0;if(e.length===1)return Lt.navigate(o?{name:e[0],params:o}:{name:e[0]});let n=o?{screen:e[e.length-1],params:o}:{screen:e[e.length-1]};for(let r=e.length-2;r>=1;r--)n={screen:e[r],params:n};return Lt.navigate({name:e[0],params:n})}function pt({visible:e,onClose:t,onBack:o,onMinimize:n,enableSharedModalDimensions:r=!1,inline:a=!1,remote:l}){let c=Nr(),i=void 0,m=Lr(),[T,v]=Vt(Qe.routeEvents.activeTab(),"events",Qr),[k,B]=Fe(!1),[ce,J]=Fe(""),z=Jr(),N=Kr("routeEvents.entries");mo(()=>{k&&z&&B(!1)},[k,z]);let[D,ae]=Vt(Qe.routeEvents.isMonitoring(),!0,qr),{events:I,clearEvents:Z,isListening:Re}=Rt({enabled:D}),H=D&ℜmo(()=>{ne.setBootCapture(D)},[D]);let[ge,L]=Fe(!1),[A,ie]=Fe(null),[pe,Ce]=Fe(1),[ye,h]=Fe(""),[V,Q]=Vt(Qe.routeEvents.eventFilters(),new Set(["/_sitemap","/api","/__dev"]),Yr),he=Vr(null),b=ve(g=>{},[]),w=ve(g=>{try{if(l){if(!l.onNavigatePath)return;if(!z&&g!=="/"){B(!0);return}l.onNavigatePath(g);return}if(m)c.push(g);else if(i){let{pathname:F,params:U}=Gt(g),xe=F.startsWith("/")?F.slice(1):F,De=Object.keys(U).length>0,Ze=i.getRootState?.();if(Ze){let Pe=yo(Ze,xe);if(Pe){let Xe=Zr(Pe,U);if(Xe){i.dispatch(Xe);return}}}i.dispatch(Lt.navigate(De?{name:xe,params:U}:{name:xe}))}else j.alert("Navigation Unavailable","No Expo Router or React Navigation container was found in this app.")}catch(F){j.alert("Navigation Error",String(F))}},[c,i,m,l,z]),oe=ve(()=>{ae(g=>!g)},[]),Oe=ve(()=>{if(I.length!==0){if(!z){B(!0);return}Z()}},[I.length,z,Z]),$e=ve(g=>{Q(F=>{let U=new Set(F);return U.has(g)?U.delete(g):U.add(g),U})},[]),dt=ve(g=>{Q(F=>new Set([...F,g]))},[]),de=ve(()=>{L(!ge)},[ge]),Te=ve((g,F)=>{ie(g),Ce(F)},[]),Ye=ve(()=>{ie(null)},[]),Io=ve(g=>{ie(null),v(g)},[]),Eo=We(()=>{let g=new Set;return I.forEach(F=>{F.pathname&&g.add(F.pathname)}),Array.from(g).sort()},[I]),we=We(()=>I.filter(g=>{if(!g.pathname||Array.from(V).some(U=>g.pathname.includes(U)))return!1;if(ye.trim()){let U=ye.toLowerCase(),xe=g.pathname.toLowerCase().includes(U),De=Object.entries(g.params||{}).some(([Ze,Pe])=>{let Xe=Array.isArray(Pe)?Pe.join(" "):Pe;return Ze.toLowerCase().includes(U)||Xe.toLowerCase().includes(U)});return xe||De}return!0}),[I,V,ye]),ko=We(()=>we.slice(0,N),[we,N]),mt=We(()=>Math.max(0,we.length-N),[we.length,N]),ft=We(()=>{let g=new Map,F=new Map;for(let U=I.length-1;U>=0;U--){let xe=I[U],De=(g.get(xe.pathname)||0)+1;g.set(xe.pathname,De),F.set(xe,De)}return F},[I]),Do=We(()=>({summary:{total:I.length,filtered:we.length,listening:H,ignoredPatterns:Array.from(V),timestamp:new Date().toISOString()},events:we.map((g,F)=>({index:F,visitNumber:ft.get(g)||1,pathname:g.pathname,timestamp:g.timestamp,timestampRelative:zr(g.timestamp),params:g.params,segments:g.segments,previousPathname:g.previousPathname,timeSincePrevious:g.timeSincePrevious}))}),[I.length,we,H,V,ft]);if(!e)return null;let Po=r?Qe.modal.root():Qe.routeEvents.modal(),gt=null,$t=()=>{if(A)return x(Tt,{event:A,visitNumber:pe,onNavigate:w});if(T==="routes")return m||l?.sitemap?x(Ae,{style:_.contentWrapper,injectedRoutes:l?.sitemap?.routes,injectedSource:l?.sitemap?.source??null,injectedLastUpdatedAt:l?.sitemap?.lastUpdatedAt??null,onNavigateRoute:l?Bo:void 0}):x(Ae,{style:_.contentWrapper});if(T==="stack")return x(Dt,{style:_.contentWrapper,injectedStack:l?l.stack??[]:void 0,onAction:l?.onStackAction,onCopyValueChange:J});if(ge)return x(Jt,{ignoredPatterns:V,onTogglePattern:$e,onAddPattern:dt,availablePathnames:Eo});let g=I.length>0;return we.length===0?ue(s,{style:_.contentWrapper,testID:"buoy-routes-events",children:[g&&x(s,{style:_.searchContainer,testID:"buoy-routes-search-field",children:x(fo,{value:ye,onChange:h,placeholder:"Search pathname or params...",testID:"buoy-routes-search"})}),x(Fr,{testID:"buoy-routes-empty",...Wr({subject:"route events",search:ye,total:I.length,capturing:H,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"}})})]}):ue(s,{style:_.contentWrapper,testID:"buoy-routes-events",children:[x(s,{style:_.searchContainer,testID:"buoy-routes-search-field",children:x(fo,{value:ye,onChange:h,placeholder:"Search pathname or params...",testID:"buoy-routes-search"})}),mt>0&&ue(s,{style:_.lockedEventsBanner,testID:"buoy-routes-locked-banner",children:[x(Ur,{size:14,color:Y.color.warning}),ue(p,{style:_.lockedEventsBannerText,testID:"buoy-routes-locked-banner-text",children:[mt," older ",mt===1?"event":"events"," locked"]}),x(p,{style:_.lockedEventsBannerSubtext,children:"Upgrade to Pro for full history"})]}),x(po,{events:ko,visitCounts:ft,onNavigate:w,onSelectEvent:Te})]})},zt=A?ue(fe,{children:[x(fe.Navigation,{onBack:Ye}),x(fe.Content,{title:A.pathname,testID:"buoy-routes-detail-title"}),x(fe.Actions,{children:x(Nt,{testID:"buoy-routes-detail-copy",value:{pathname:A.pathname,previousPathname:A.previousPathname,params:A.params,segments:A.segments,timestamp:A.timestamp,timestampISO:new Date(A.timestamp).toISOString(),timeSincePrevious:A.timeSincePrevious,visitNumber:pe},buttonStyle:_.iconButton})})]}):ge?ue(fe,{children:[x(fe.Navigation,{onBack:()=>L(!1)}),x(fe.Content,{title:"Filters",testID:"buoy-routes-filters-title"})]}):ue(fe,{children:[o&&x(fe.Navigation,{onBack:o}),x(fe.Content,{title:"",noMargin:!0,children:x($r,{tabs:[{key:"routes",label:m?"Routes":"Screens"},{key:"events",label:`Events${I.length>0&&T!=="events"?` (${I.length})`:""}`},{key:"stack",label:"Stack"}],activeTab:T,onTabChange:g=>Io(g),testIDPrefix:"buoy-routes-tab"})}),ue(fe.Actions,{children:[T==="stack"&&x(Nt,{value:ce,buttonStyle:_.iconButton,testID:"buoy-routes-stack-copy"}),T==="events"&&ue(ea,{children:[x(Nt,{value:Do,buttonStyle:_.iconButton,testID:"buoy-routes-copy"}),x(W,{onPress:de,style:[_.iconButton,V.size>0&&_.activeFilterButton],testID:"buoy-routes-filters",accessibilityRole:"button",accessibilityLabel:V.size>0?`Route filters, ${V.size} active`:"Route filters",children:x(Hr,{size:14,color:V.size>0?Y.color.accent:Y.color.textSecondary})}),x(Gr,{isEnabled:H,onToggle:oe,accessibilityLabel:"Toggle route event monitoring",testID:"buoy-routes-power"}),x(W,{onPress:Oe,style:_.iconButton,testID:"buoy-routes-clear",accessibilityRole:"button",accessibilityLabel:"Clear route events",children:x(Mr,{size:14,color:Y.color.danger})})]})]})]}),Bo=g=>{if(g.type==="layout"||g.type==="group")return;let F=g.type==="index"||g.path==="/";if(!z&&!F){B(!0);return}l?.onNavigateRoute?.(g)},Mt=x(jr,{visible:k,onClose:()=>B(!1),featureName:"Route Event Management"});return a?ue(go,{children:[ue(s,{style:_.inlineRoot,children:[x(s,{style:_.inlineHeader,...Ar,children:zt}),$t(),gt]}),Mt]}):x(go,{children:ue(Or,{visible:e,onClose:t,onMinimize:n,persistenceKey:Po,header:{showToggleButton:!0,customContent:zt},onModeChange:b,enablePersistence:!0,initialMode:"bottomSheet",enableGlitchEffects:!0,disableScrollWrapper:!0,styles:{},footer:gt,footerHeight:gt?68:0,children:[$t(),Mt]})})}function Xr(e={}){return x(pt,{...e,inline:!0,visible:!0,onClose:()=>{}})}var _=X.create({inlineRoot:{flex:1,minHeight:0,backgroundColor:"transparent"},inlineHeader:{paddingHorizontal:12,paddingVertical:8,borderBottomWidth:1,borderBottomColor:_r.border,backgroundColor:"transparent"},iconButton:{padding:6,borderRadius:6,backgroundColor:Y.color.buttonSurface},activeFilterButton:{backgroundColor:Y.color.accentSoft},emptyState:{flex:1,justifyContent:"center",alignItems:"center",padding:32},emptyTitle:{color:Y.color.text,fontSize:16,fontWeight:"600",marginTop:16,marginBottom:8,fontFamily:ct,letterSpacing:.5,textTransform:"uppercase"},emptySubtitle:{color:Y.color.textSecondary,fontSize:14,textAlign:"center",fontFamily:ct},contentWrapper:{flex:1},statsContainer:{paddingHorizontal:16,paddingVertical:8,backgroundColor:Y.color.surface,borderBottomWidth:1,borderBottomColor:Y.color.border},statsText:{fontSize:11,color:Y.color.textSecondary,fontFamily:ct,textAlign:"center"},statsWarning:{color:Y.color.warning,fontWeight:"600"},searchContainer:{paddingHorizontal:16,paddingVertical:8,backgroundColor:"transparent"},lockedEventsBanner:{flexDirection:"row",alignItems:"center",gap:8,backgroundColor:Y.color.warningSoft,borderWidth:1,borderColor:Y.color.warning+"30",borderRadius:8,paddingVertical:10,paddingHorizontal:14,marginHorizontal:16,marginBottom:8},lockedEventsBannerText:{fontSize:12,fontWeight:"600",color:Y.color.warning,fontFamily:ct},lockedEventsBannerSubtext:{fontSize:11,color:Y.color.textSecondary,marginLeft:"auto"}});import{createToolFactory as oa,defineToolPreset as na}from"@buoy-gg/shared-ui/web";import{jsx as aa}from"react/jsx-runtime";var ho=na({id:"route-events",name:"ROUTES",description:"Route tracking & navigation inspector",slot:"both",icon:({size:e})=>aa(ta,{size:e}),component:pt,props:{enableSharedModalDimensions:!1}}),ra=oa(ho,e=>({enableSharedModalDimensions:e.enableSharedModalDimensions??!1}));import{useEffect as la}from"react";import{browserRouter as bo,getBrowserHref as ia,getBrowserRouteURL as vo,subscribeBrowserNavigation as sa}from"@buoy-gg/shared-ui/web/utils";var Ro=0,At;function xo(){if(typeof window>"u")return()=>{};if(Ro++===0){ne.hydrateBootCapture();let t,o,n="",r=[],a=-1,l=i=>{if(i.href===n&&i.kind==="pop")return;if(i.kind==="replace"&&a>=0)r[a]=i.href;else if(i.kind==="pop"){let v=r.lastIndexOf(i.href,a-1),k=r.indexOf(i.href,a+1);v>=0?a=v:k>=0?a=k:(r.splice(a+1),r.push(i.href),a++)}else r.splice(a+1),r.push(i.href),a++;n=i.href;let m=vo(i.href),T=Date.now();Se.emit({pathname:m.pathname,params:Object.fromEntries(m.searchParams),segments:m.pathname.split("/").filter(Boolean),previousPathname:t,timestamp:T,timeSincePrevious:o===void 0?void 0:T-o}),t=m.pathname,o=T,G.setStack(r.map((v,k)=>{let B=vo(v);return{key:`browser:${k}`,name:B.pathname,pathname:B.pathname,params:Object.fromEntries(B.searchParams),index:k,isFocused:k===a,canPop:k>0}}))},c=i=>{if(!Number.isInteger(i)||i<0||i>=r.length)throw new Error("That browser history entry is unavailable.");window.history.go(i-a)};G.setActions({navigateToIndex:c,popToIndex:c,goBack:bo.back,popToTop:()=>c(0),navigateToRoute:(i,m)=>(bo.push({pathname:i,params:m}),!0)}),At=sa(l),l({href:ia(),kind:"initial"})}let e=!1;return()=>{e||(e=!0,--Ro===0&&(At?.(),At=void 0,G.setActions(null)))}}function ua(){return la(xo,[]),null}import{useEffect as So,useRef as Ft}from"react";import{useSafePathname as ca,useSafeSegments as pa,useSafeGlobalSearchParams as da}from"@buoy-gg/shared-ui/web";function ma(e){let t=ca(),o=pa(),n=da(),r=Ft(e),a=Ft(void 0),l=Ft(void 0);So(()=>{r.current=e},[e]),So(()=>{let c=Date.now(),i=l.current?c-l.current:void 0,m={pathname:t,params:n,segments:o,timestamp:c,previousPathname:a.current,timeSincePrevious:i};a.current=t,l.current=c,Se.emit(m),r.current&&r.current(m)},[t,o,n])}import{useEffect as To,useRef as Wt}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 n=Co(t.state);if(n.route)return{route:n.route,segments:[...o,...n.segments]}}return{route:t,segments:o}}function wo(e,t,o,n){if(!e)return;let{route:r,segments:a}=Co(e);if(!r)return;let l=`/${r.name}`;if(l===t.current)return;let c=Date.now(),i=o.current?c-o.current:void 0,m={pathname:l,params:r.params||{},segments:a,timestamp:c,previousPathname:t.current,timeSincePrevious:i};t.current=l,o.current=c,Se.emit(m),n.current&&n.current(m)}function fa(e){let t=void 0,o=Wt(e),n=Wt(void 0),r=Wt(void 0);To(()=>{o.current=e},[e]),To(()=>{if(!t)return;let a=t.getRootState?.();a&&wo(a,n,r,o);let l=t.addListener?.("state",()=>{let c=t.getRootState?.();wo(c,n,r,o)});return()=>{l?.()}},[t])}import{getSafeRouter as ga}from"@buoy-gg/shared-ui/web";import{isOverWireBudget as ya}from"@buoy-gg/shared-ui/web";var ha=16*1024,ba=Object.freeze({__buoyOmitted:"route-params",note:"Navigation params stay on the device."});function Ot(e){return e==null?!1:ya(e,ha)}function qe(e){return Ot(e)?ba:e}function va(e){return Ot(e.params)?{...e,params:qe(e.params)}:e}function Ra(e){return Ot(e.params)?{...e,params:qe(e.params)}:e}function xa(){let e=je();return{routes:re.parseRouteTree(Ee()),source:e.source,lastUpdatedAt:e.lastLoadedAt}}var Sa={version:3,getSnapshot:()=>({events:ne.getEvents().map(va),sitemap:xa(),stack:G.getStack().map(Ra)}),subscribe:e=>{let t=ne.subscribeToEvents(e),o=G.subscribe(e),n=null;if(!Ee()){let r=0,a=100,l=()=>{if(r+=1,Ee()){n=null,e();return}n=r<a?setTimeout(l,100):null};n=setTimeout(l,100)}return()=>{t(),o(),n&&clearTimeout(n)}},actions:{clearEvents:()=>{ne.clearEvents()},getCurrentRoute:()=>{let e=ne.getEvents()[0];if(e&&ne.isCapturing())return{path:e.pathname,params:qe(e.params),at:e.timestamp,source:"event"};let t=G.getStack(),o=t.find(n=>n.isFocused)??t[t.length-1];return o?.pathname?{path:o.pathname,params:qe(o.params??{}),at:null,source:"stack"}:e?{path:e.pathname,params:qe(e.params),at:e.timestamp,source:"event",stale:!0}:{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 n=ga();if(!n){let a=G.getActions(),l=o.replace(/^\//,"");if(!a?.navigateToRoute||!l)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(l,t?.params))throw new Error(`Could not navigate to "${l}" \u2014 no navigation container is live.`);return{navigated:o,replaced:!1,via:"react-navigation"}}return(t?.replace===!0&&typeof n.replace=="function"?n.replace:n.navigate)(o),{navigated:o,replaced:t?.replace===!0}},stackNavigateToIndex:e=>{let t=e?.index;if(typeof t!="number")throw new Error("stackNavigateToIndex requires a numeric 'index'");let o=G.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=G.getActions();if(!o)throw new Error("navigation stack is not available");return o.popToIndex(t),{poppedToIndex:t}},stackGoBack:()=>{let e=G.getActions();if(!e)throw new Error("navigation stack is not available");return e.goBack(),{wentBack:!0}},stackPopToTop:()=>{let e=G.getActions();if(!e)throw new Error("navigation stack is not available");return e.popToTop(),{poppedToTop:!0}}}};export{Dt as NavigationStack,Tt as RouteEventDetail,Me as RouteEventExpandedContent,Pt as RouteEventItemCompact,pt as RouteEventsModalWithTabs,et as RouteObserver,re as RouteParser,ua as RouteTracker,Ae as RoutesSitemap,Xr as RoutesToolView,ra as createRouteEventsTool,G as navigationStackStore,jn as registerBrowserRoutes,ne as routeEventStore,Sa as routeEventsSyncAdapter,ho as routeEventsToolPreset,Se as routeObserver,kt as useNavigationStack,Qn as useParentRoutes,Jn as useRoute,Rt as useRouteEvents,ma as useRouteObserver,fa as useRouteObserverReactNavigation,Ge 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}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};
|