@buoy-gg/route-events 7.0.39 → 7.0.41
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 +4 -0
- package/lib/commonjs/RouteTracker.web.js +12 -0
- package/lib/commonjs/browserRouteRegistry.js +30 -0
- package/lib/commonjs/browserRoutes.js +96 -0
- package/lib/commonjs/components/ReactNavigationRoutes.web.js +12 -0
- package/lib/commonjs/components/RouteEventDetail.js +1 -1
- package/lib/commonjs/components/RouteEventItemCompact.js +1 -1
- package/lib/commonjs/components/RouteEventsModalWithTabs.js +24 -7
- package/lib/commonjs/expoRouterStore.web.js +44 -0
- package/lib/commonjs/index.js +7 -0
- package/lib/commonjs/useNavigationStack.web.js +32 -0
- package/lib/commonjs/utils/routeTemplate.js +51 -0
- package/lib/commonjs/utils/safeReactNavigation.web.js +36 -0
- package/lib/module/RouteTracker.web.js +8 -0
- package/lib/module/browserRouteRegistry.js +24 -0
- package/lib/module/browserRoutes.js +92 -0
- package/lib/module/components/ReactNavigationRoutes.web.js +3 -0
- package/lib/module/components/RouteEventDetail.js +2 -2
- package/lib/module/components/RouteEventItemCompact.js +2 -2
- package/lib/module/components/RouteEventsModalWithTabs.js +24 -7
- package/lib/module/expoRouterStore.web.js +37 -0
- package/lib/module/index.js +1 -0
- package/lib/module/useNavigationStack.web.js +28 -0
- package/lib/module/utils/routeTemplate.js +49 -0
- package/lib/module/utils/safeReactNavigation.web.js +27 -0
- package/lib/typescript/RouteTracker.web.d.ts +2 -0
- package/lib/typescript/RouteTracker.web.d.ts.map +1 -0
- package/lib/typescript/browserRouteRegistry.d.ts +4 -0
- package/lib/typescript/browserRouteRegistry.d.ts.map +1 -0
- package/lib/typescript/browserRoutes.d.ts +2 -0
- package/lib/typescript/browserRoutes.d.ts.map +1 -0
- package/lib/typescript/components/ReactNavigationRoutes.web.d.ts +2 -0
- package/lib/typescript/components/ReactNavigationRoutes.web.d.ts.map +1 -0
- package/lib/typescript/components/RouteEventsModalWithTabs.d.ts.map +1 -1
- package/lib/typescript/expoRouterStore.web.d.ts +13 -0
- package/lib/typescript/expoRouterStore.web.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +1 -0
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/useNavigationStack.web.d.ts +4 -0
- package/lib/typescript/useNavigationStack.web.d.ts.map +1 -0
- package/lib/typescript/utils/routeTemplate.d.ts +13 -0
- package/lib/typescript/utils/routeTemplate.d.ts.map +1 -1
- package/lib/typescript/utils/safeReactNavigation.web.d.ts +22 -0
- package/lib/typescript/utils/safeReactNavigation.web.d.ts.map +1 -0
- package/lib/web/index.mjs +7 -0
- package/package.json +33 -13
|
@@ -22,6 +22,7 @@ import { RoutesSitemap } from "./RoutesSitemap";
|
|
|
22
22
|
import { ReactNavigationRoutes } from "./ReactNavigationRoutes";
|
|
23
23
|
import { NavigationStack } from "./NavigationStack";
|
|
24
24
|
import { RouteEventsTimeline } from "./RouteEventsTimeline";
|
|
25
|
+
import { splitRouteHref } from "../utils/routeTemplate";
|
|
25
26
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
26
27
|
/** Persistence recipes: the tab is stored as its bare name, the flag as "true"/"false". */
|
|
27
28
|
const TAB_PERSISTENCE = {
|
|
@@ -65,16 +66,23 @@ function findScreenPath(state, screenName) {
|
|
|
65
66
|
* e.g. ["MainApp", "Settings", "SettingScreen"] becomes:
|
|
66
67
|
* navigate("MainApp", { screen: "Settings", params: { screen: "SettingScreen" } })
|
|
67
68
|
*/
|
|
68
|
-
function buildNestedNavigateAction(path) {
|
|
69
|
+
function buildNestedNavigateAction(path, leafParams) {
|
|
69
70
|
if (path.length === 0) return null;
|
|
71
|
+
const leaf = leafParams && Object.keys(leafParams).length > 0 ? leafParams : undefined;
|
|
70
72
|
if (path.length === 1) {
|
|
71
|
-
return CommonActions.navigate({
|
|
73
|
+
return CommonActions.navigate(leaf ? {
|
|
74
|
+
name: path[0],
|
|
75
|
+
params: leaf
|
|
76
|
+
} : {
|
|
72
77
|
name: path[0]
|
|
73
78
|
});
|
|
74
79
|
}
|
|
75
80
|
|
|
76
81
|
// Build nested params from the end
|
|
77
|
-
let params = {
|
|
82
|
+
let params = leaf ? {
|
|
83
|
+
screen: path[path.length - 1],
|
|
84
|
+
params: leaf
|
|
85
|
+
} : {
|
|
78
86
|
screen: path[path.length - 1]
|
|
79
87
|
};
|
|
80
88
|
for (let i = path.length - 2; i >= 1; i--) {
|
|
@@ -172,15 +180,21 @@ export function RouteEventsModalWithTabs({
|
|
|
172
180
|
if (hasExpoRouter) {
|
|
173
181
|
router.push(pathname);
|
|
174
182
|
} else if (containerRef) {
|
|
175
|
-
// On RN CLI, pathname is /<ScreenName> — extract the screen name
|
|
176
|
-
|
|
183
|
+
// On RN CLI, pathname is /<ScreenName> — extract the screen name.
|
|
184
|
+
// A recorded event's href may carry its params as a query string.
|
|
185
|
+
const {
|
|
186
|
+
pathname: path,
|
|
187
|
+
params: routeParams
|
|
188
|
+
} = splitRouteHref(pathname);
|
|
189
|
+
const screenName = path.startsWith("/") ? path.slice(1) : path;
|
|
190
|
+
const hasParams = Object.keys(routeParams).length > 0;
|
|
177
191
|
|
|
178
192
|
// Walk the state tree to find the nesting path to this screen
|
|
179
193
|
const rootState = containerRef.getRootState?.();
|
|
180
194
|
if (rootState) {
|
|
181
195
|
const path = findScreenPath(rootState, screenName);
|
|
182
196
|
if (path) {
|
|
183
|
-
const action = buildNestedNavigateAction(path);
|
|
197
|
+
const action = buildNestedNavigateAction(path, routeParams);
|
|
184
198
|
if (action) {
|
|
185
199
|
containerRef.dispatch(action);
|
|
186
200
|
return;
|
|
@@ -189,7 +203,10 @@ export function RouteEventsModalWithTabs({
|
|
|
189
203
|
}
|
|
190
204
|
|
|
191
205
|
// Fallback: try direct navigation (works for top-level screens)
|
|
192
|
-
containerRef.dispatch(CommonActions.navigate({
|
|
206
|
+
containerRef.dispatch(CommonActions.navigate(hasParams ? {
|
|
207
|
+
name: screenName,
|
|
208
|
+
params: routeParams
|
|
209
|
+
} : {
|
|
193
210
|
name: screenName
|
|
194
211
|
}));
|
|
195
212
|
} else {
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { getBrowserHref } from '@buoy-gg/shared-ui/utils';
|
|
4
|
+
import { getBrowserRoutePaths, getBrowserRoutesUpdatedAt } from './browserRouteRegistry';
|
|
5
|
+
export function isExpoRouterStoreSupported() {
|
|
6
|
+
return typeof window !== 'undefined';
|
|
7
|
+
}
|
|
8
|
+
export function loadRouteNode() {
|
|
9
|
+
if (!isExpoRouterStoreSupported()) return null;
|
|
10
|
+
const paths = new Set([...getBrowserRoutePaths(), new URL(getBrowserHref()).pathname]);
|
|
11
|
+
return {
|
|
12
|
+
route: '',
|
|
13
|
+
type: 'layout',
|
|
14
|
+
contextKey: 'browser',
|
|
15
|
+
children: [...paths].map(path => ({
|
|
16
|
+
route: path.replace(/^\//, '') || 'index',
|
|
17
|
+
type: 'route',
|
|
18
|
+
contextKey: path,
|
|
19
|
+
children: [],
|
|
20
|
+
dynamic: null
|
|
21
|
+
}))
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
export function getExpoRouterStore() {
|
|
25
|
+
return {
|
|
26
|
+
routeNode: loadRouteNode(),
|
|
27
|
+
navigationRef: {
|
|
28
|
+
isReady: () => typeof window !== 'undefined'
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
export function getRouteNodeMetadata() {
|
|
33
|
+
return {
|
|
34
|
+
source: null,
|
|
35
|
+
lastLoadedAt: getBrowserRoutesUpdatedAt()
|
|
36
|
+
};
|
|
37
|
+
}
|
package/lib/module/index.js
CHANGED
|
@@ -24,6 +24,7 @@ export { RouteEventsModalWithTabs, RoutesToolView } from "./components/RouteEven
|
|
|
24
24
|
// ROUTE TRACKER (Required - place inside your navigation tree)
|
|
25
25
|
// =============================================================================
|
|
26
26
|
export { RouteTracker } from "./RouteTracker";
|
|
27
|
+
export { registerBrowserRoutes } from "./browserRouteRegistry";
|
|
27
28
|
|
|
28
29
|
// =============================================================================
|
|
29
30
|
// COMPONENTS (For custom UI implementations)
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { useSyncExternalStore } from 'react';
|
|
4
|
+
import { navigationStackStore } from './stores/navigationStackStore';
|
|
5
|
+
const empty = [];
|
|
6
|
+
export function useNavigationStack() {
|
|
7
|
+
const stack = useSyncExternalStore(callback => navigationStackStore.subscribe(callback), () => navigationStackStore.getStack(), () => empty);
|
|
8
|
+
const focused = stack.find(item => item.isFocused) ?? null;
|
|
9
|
+
const actions = () => {
|
|
10
|
+
const current = navigationStackStore.getActions();
|
|
11
|
+
if (!current) throw new Error('Mount RouteTracker to capture browser navigation.');
|
|
12
|
+
return current;
|
|
13
|
+
};
|
|
14
|
+
return {
|
|
15
|
+
stack,
|
|
16
|
+
focusedRoute: focused,
|
|
17
|
+
stackDepth: stack.length,
|
|
18
|
+
isAtRoot: !focused || focused.index === 0,
|
|
19
|
+
isLoaded: stack.length > 0,
|
|
20
|
+
error: null,
|
|
21
|
+
refresh: () => {},
|
|
22
|
+
navigateToIndex: index => actions().navigateToIndex(index),
|
|
23
|
+
navigateToRoute: (name, params) => actions().navigateToRoute?.(name, params) ?? false,
|
|
24
|
+
popToIndex: index => actions().popToIndex(index),
|
|
25
|
+
goBack: () => actions().goBack(),
|
|
26
|
+
popToTop: () => actions().popToTop()
|
|
27
|
+
};
|
|
28
|
+
}
|
|
@@ -21,4 +21,53 @@ export function getRouteTemplate(pathname, segments) {
|
|
|
21
21
|
});
|
|
22
22
|
const template = "/" + templateParts.join("/");
|
|
23
23
|
return template !== pathname ? template : null;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* The href that reopens a recorded route: its pathname plus the params that are
|
|
28
|
+
* not already in the path, as a query string. Expo Router reports dynamic
|
|
29
|
+
* segment values (`/order/42` → `{ id: "42" }`) and search params (`?menu=1`)
|
|
30
|
+
* in one `params` object; only the second kind needs to be carried, because the
|
|
31
|
+
* first is already in the pathname.
|
|
32
|
+
*/
|
|
33
|
+
export function routeHref(pathname, params) {
|
|
34
|
+
if (!params) return pathname;
|
|
35
|
+
const inPath = new Set(pathname.split("/").filter(Boolean).map(seg => {
|
|
36
|
+
try {
|
|
37
|
+
return decodeURIComponent(seg);
|
|
38
|
+
} catch {
|
|
39
|
+
return seg;
|
|
40
|
+
}
|
|
41
|
+
}));
|
|
42
|
+
const query = [];
|
|
43
|
+
for (const [key, raw] of Object.entries(params)) {
|
|
44
|
+
const values = Array.isArray(raw) ? raw : [raw];
|
|
45
|
+
// A catch-all segment's values, or one dynamic segment's value.
|
|
46
|
+
if (values.length > 0 && values.every(v => inPath.has(String(v)))) continue;
|
|
47
|
+
for (const v of values) query.push(`${encodeURIComponent(key)}=${encodeURIComponent(String(v))}`);
|
|
48
|
+
}
|
|
49
|
+
return query.length ? `${pathname}?${query.join("&")}` : pathname;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** Split an href from {@link routeHref} back into its path and params. */
|
|
53
|
+
export function splitRouteHref(href) {
|
|
54
|
+
const q = href.indexOf("?");
|
|
55
|
+
if (q < 0) return {
|
|
56
|
+
pathname: href,
|
|
57
|
+
params: {}
|
|
58
|
+
};
|
|
59
|
+
const params = {};
|
|
60
|
+
for (const pair of href.slice(q + 1).split("&")) {
|
|
61
|
+
if (!pair) continue;
|
|
62
|
+
const [k, v = ""] = pair.split("=");
|
|
63
|
+
try {
|
|
64
|
+
params[decodeURIComponent(k)] = decodeURIComponent(v);
|
|
65
|
+
} catch {
|
|
66
|
+
params[k] = v;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
pathname: href.slice(0, q),
|
|
71
|
+
params
|
|
72
|
+
};
|
|
24
73
|
}
|
|
@@ -0,0 +1,27 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RouteTracker.web.d.ts","sourceRoot":"","sources":["../../src/RouteTracker.web.tsx"],"names":[],"mappings":"AAEA,wBAAgB,YAAY,SAA4D"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browserRouteRegistry.d.ts","sourceRoot":"","sources":["../../src/browserRouteRegistry.ts"],"names":[],"mappings":"AAEA,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,IAAI,CAU1E;AACD,wBAAgB,oBAAoB,aAAmC;AACvE,wBAAgB,yBAAyB,kBAAwB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browserRoutes.d.ts","sourceRoot":"","sources":["../../src/browserRoutes.ts"],"names":[],"mappings":"AAQA,wBAAgB,wBAAwB,IAAI,MAAM,IAAI,CA0CrD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ReactNavigationRoutes.web.d.ts","sourceRoot":"","sources":["../../../src/components/ReactNavigationRoutes.web.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,IAAI,qBAAqB,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RouteEventsModalWithTabs.d.ts","sourceRoot":"","sources":["../../../src/components/RouteEventsModalWithTabs.tsx"],"names":[],"mappings":"AA0DA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAGhD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"RouteEventsModalWithTabs.d.ts","sourceRoot":"","sources":["../../../src/components/RouteEventsModalWithTabs.tsx"],"names":[],"mappings":"AA0DA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAGhD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AAInE,MAAM,WAAW,6BAA6B;IAC5C,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,GAAG,KAAK,IAAI,CAAC;IACvC,2BAA2B,CAAC,EAAE,OAAO,CAAC;IACtC;;;;;OAKG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;;OAKG;IACH,MAAM,CAAC,EAAE;QACP,OAAO,CAAC,EAAE;YACR,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC;YACrB,MAAM,CAAC,EAAE,OAAO,GAAG,KAAK,GAAG,IAAI,CAAC;YAChC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;SAC/B,CAAC;QACF,KAAK,CAAC,EAAE,gBAAgB,EAAE,CAAC;QAC3B;;;;WAIG;QACH,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,CAAC;QAC7C;;;;;WAKG;QACH,cAAc,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;QAC5C,2EAA2E;QAC3E,aAAa,CAAC,EAAE,CACd,MAAM,EAAE,yBAAyB,EACjC,OAAO,CAAC,EAAE;YAAE,KAAK,CAAC,EAAE,MAAM,CAAA;SAAE,KACzB,IAAI,CAAC;KACX,CAAC;CACH;AAiED,wBAAgB,wBAAwB,CAAC,EACvC,OAAO,EACP,OAAO,EACP,MAAM,EACN,UAAU,EACV,2BAAmC,EACnC,MAAc,EACd,MAAM,GACP,EAAE,6BAA6B,sCA+mB/B;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,KAAK,GAAE,IAAI,CAAC,6BAA6B,EAAE,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAM,+BAKlF"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare function isExpoRouterStoreSupported(): boolean;
|
|
2
|
+
export declare function loadRouteNode(): any;
|
|
3
|
+
export declare function getExpoRouterStore(): {
|
|
4
|
+
routeNode: any;
|
|
5
|
+
navigationRef: {
|
|
6
|
+
isReady: () => boolean;
|
|
7
|
+
};
|
|
8
|
+
};
|
|
9
|
+
export declare function getRouteNodeMetadata(): {
|
|
10
|
+
source: 'build' | 'src' | null;
|
|
11
|
+
lastLoadedAt: number | null;
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=expoRouterStore.web.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"expoRouterStore.web.d.ts","sourceRoot":"","sources":["../../src/expoRouterStore.web.ts"],"names":[],"mappings":"AAEA,wBAAgB,0BAA0B,YAA4C;AACtF,wBAAgB,aAAa,IAAI,GAAG,CAMnC;AACD,wBAAgB,kBAAkB;;;;;EAA8G;AAChJ,wBAAgB,oBAAoB,IAAI;IAAE,MAAM,EAAE,OAAO,GAAG,KAAK,GAAG,IAAI,CAAC;IAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAwE"}
|
|
@@ -10,6 +10,7 @@ export { routeEventsToolPreset, createRouteEventsTool } from "./preset";
|
|
|
10
10
|
export { RouteEventsModalWithTabs, RoutesToolView, } from "./components/RouteEventsModalWithTabs";
|
|
11
11
|
export type { RouteEventsModalWithTabsProps } from "./components/RouteEventsModalWithTabs";
|
|
12
12
|
export { RouteTracker } from "./RouteTracker";
|
|
13
|
+
export { registerBrowserRoutes } from "./browserRouteRegistry";
|
|
13
14
|
export { RoutesSitemap } from "./components/RoutesSitemap";
|
|
14
15
|
export type { RoutesSitemapProps } from "./components/RoutesSitemap";
|
|
15
16
|
export { NavigationStack } from "./components/NavigationStack";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAOxE,OAAO,EACL,wBAAwB,EACxB,cAAc,GACf,MAAM,uCAAuC,CAAC;AAC/C,YAAY,EAAE,6BAA6B,EAAE,MAAM,uCAAuC,CAAC;AAK3F,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAOxE,OAAO,EACL,wBAAwB,EACxB,cAAc,GACf,MAAM,uCAAuC,CAAC;AAC/C,YAAY,EAAE,6BAA6B,EAAE,MAAM,uCAAuC,CAAC;AAK3F,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAK/D,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,YAAY,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAC/D,YAAY,EACV,oBAAoB,EACpB,yBAAyB,GAC1B,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AAC3E,YAAY,EAAE,0BAA0B,EAAE,MAAM,oCAAoC,CAAC;AACrF,OAAO,EAAE,yBAAyB,EAAE,MAAM,wCAAwC,CAAC;AACnF,YAAY,EAAE,8BAA8B,EAAE,MAAM,wCAAwC,CAAC;AAC7F,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,YAAY,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAK3E,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,+BAA+B,EAAE,MAAM,mCAAmC,CAAC;AACpF,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,YAAY,EACV,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAC/E,YAAY,EACV,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,YAAY,EACV,wBAAwB,EACxB,gBAAgB,GACjB,MAAM,sBAAsB,CAAC;AAK9B,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AACvE,YAAY,EACV,oBAAoB,EACpB,sBAAsB,GACvB,MAAM,+BAA+B,CAAC;AAKvC,YAAY,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,YAAY,EACV,SAAS,EACT,SAAS,EACT,UAAU,EACV,UAAU,GACX,MAAM,eAAe,CAAC;AAKvB,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAKhD,qEAAqE;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,qEAAqE;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,YAAY,EACV,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,0BAA0B,CAAC;AAClC;;iDAEiD;AACjD,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,YAAY,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { UseNavigationStackResult } from './useNavigationStack';
|
|
2
|
+
export type { UseNavigationStackResult, StackDisplayItem } from './useNavigationStack';
|
|
3
|
+
export declare function useNavigationStack(): UseNavigationStackResult;
|
|
4
|
+
//# sourceMappingURL=useNavigationStack.web.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useNavigationStack.web.d.ts","sourceRoot":"","sources":["../../src/useNavigationStack.web.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AACrE,YAAY,EAAE,wBAAwB,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAEvF,wBAAgB,kBAAkB,IAAI,wBAAwB,CAO7D"}
|
|
@@ -5,4 +5,17 @@
|
|
|
5
5
|
* matches the pathname (i.e. the route is fully static).
|
|
6
6
|
*/
|
|
7
7
|
export declare function getRouteTemplate(pathname: string, segments: string[]): string | null;
|
|
8
|
+
/**
|
|
9
|
+
* The href that reopens a recorded route: its pathname plus the params that are
|
|
10
|
+
* not already in the path, as a query string. Expo Router reports dynamic
|
|
11
|
+
* segment values (`/order/42` → `{ id: "42" }`) and search params (`?menu=1`)
|
|
12
|
+
* in one `params` object; only the second kind needs to be carried, because the
|
|
13
|
+
* first is already in the pathname.
|
|
14
|
+
*/
|
|
15
|
+
export declare function routeHref(pathname: string, params: Record<string, string | string[]> | undefined): string;
|
|
16
|
+
/** Split an href from {@link routeHref} back into its path and params. */
|
|
17
|
+
export declare function splitRouteHref(href: string): {
|
|
18
|
+
pathname: string;
|
|
19
|
+
params: Record<string, string>;
|
|
20
|
+
};
|
|
8
21
|
//# sourceMappingURL=routeTemplate.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"routeTemplate.d.ts","sourceRoot":"","sources":["../../../src/utils/routeTemplate.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAAE,GACjB,MAAM,GAAG,IAAI,CAqBf"}
|
|
1
|
+
{"version":3,"file":"routeTemplate.d.ts","sourceRoot":"","sources":["../../../src/utils/routeTemplate.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAAE,GACjB,MAAM,GAAG,IAAI,CAqBf;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CACvB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,GAAG,SAAS,GACpD,MAAM,CAsBR;AAED,0EAA0E;AAC1E,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,CAcjG"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export declare function useSafeNavigation(): {
|
|
2
|
+
push(path: string | {
|
|
3
|
+
pathname: string;
|
|
4
|
+
params?: Record<string, unknown>;
|
|
5
|
+
}): void;
|
|
6
|
+
replace(path: string | {
|
|
7
|
+
pathname: string;
|
|
8
|
+
params?: Record<string, unknown>;
|
|
9
|
+
}): void;
|
|
10
|
+
back(): void;
|
|
11
|
+
canGoBack(): boolean;
|
|
12
|
+
navigate(path: string): void;
|
|
13
|
+
setParams(params: Record<string, unknown>): void;
|
|
14
|
+
dismiss(count?: number): void;
|
|
15
|
+
dismissAll(): never;
|
|
16
|
+
};
|
|
17
|
+
export declare function useSafeNavigationState(selector: (state: any) => any): any;
|
|
18
|
+
export declare function useSafeNavigationContainerRef(): undefined;
|
|
19
|
+
export declare function getCommonActions(): null;
|
|
20
|
+
export declare function getStackActions(): null;
|
|
21
|
+
export declare function isReactNavigationAvailable(): boolean;
|
|
22
|
+
//# sourceMappingURL=safeReactNavigation.web.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"safeReactNavigation.web.d.ts","sourceRoot":"","sources":["../../../src/utils/safeReactNavigation.web.ts"],"names":[],"mappings":"AACA,wBAAgB,iBAAiB;;;cAMsG,CAAC;;;;cAA8G,CAAC;;;;;;;;EAN1L;AAC7D,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,GAAG,OAA+F;AACnK,wBAAgB,6BAA6B,IAAI,SAAS,CAAsB;AAChF,wBAAgB,gBAAgB,IAAI,IAAI,CAAiB;AACzD,wBAAgB,eAAe,IAAI,IAAI,CAAiB;AACxD,wBAAgB,0BAA0B,IAAI,OAAO,CAAkB"}
|
|
@@ -0,0 +1,7 @@
|
|
|
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}:
|
|
4
|
+
|
|
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}
|
|
6
|
+
|
|
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};
|