@buoy-gg/route-events 3.0.1 → 3.0.2

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.
Files changed (32) hide show
  1. package/lib/commonjs/RouteTracker.js +38 -4
  2. package/lib/commonjs/components/NavigationStack.js +47 -31
  3. package/lib/commonjs/components/RoutesSitemap.js +176 -133
  4. package/lib/commonjs/expoRouterStore.js +17 -0
  5. package/lib/commonjs/index.js +7 -0
  6. package/lib/commonjs/stores/navigationStackStore.js +45 -0
  7. package/lib/commonjs/sync/routeEventsSyncAdapter.js +148 -0
  8. package/lib/commonjs/useRouteSitemap.js +28 -7
  9. package/lib/module/RouteTracker.js +39 -5
  10. package/lib/module/components/NavigationStack.js +47 -31
  11. package/lib/module/components/RoutesSitemap.js +177 -134
  12. package/lib/module/expoRouterStore.js +16 -0
  13. package/lib/module/index.js +4 -0
  14. package/lib/module/stores/navigationStackStore.js +41 -0
  15. package/lib/module/sync/routeEventsSyncAdapter.js +145 -0
  16. package/lib/module/useRouteSitemap.js +29 -8
  17. package/lib/typescript/RouteTracker.d.ts.map +1 -1
  18. package/lib/typescript/components/NavigationStack.d.ts +18 -1
  19. package/lib/typescript/components/NavigationStack.d.ts.map +1 -1
  20. package/lib/typescript/components/RoutesSitemap.d.ts +19 -1
  21. package/lib/typescript/components/RoutesSitemap.d.ts.map +1 -1
  22. package/lib/typescript/expoRouterStore.d.ts +8 -0
  23. package/lib/typescript/expoRouterStore.d.ts.map +1 -1
  24. package/lib/typescript/index.d.ts +3 -1
  25. package/lib/typescript/index.d.ts.map +1 -1
  26. package/lib/typescript/stores/navigationStackStore.d.ts +33 -0
  27. package/lib/typescript/stores/navigationStackStore.d.ts.map +1 -0
  28. package/lib/typescript/sync/routeEventsSyncAdapter.d.ts +69 -0
  29. package/lib/typescript/sync/routeEventsSyncAdapter.d.ts.map +1 -0
  30. package/lib/typescript/useRouteSitemap.d.ts +17 -0
  31. package/lib/typescript/useRouteSitemap.d.ts.map +1 -1
  32. package/package.json +5 -5
@@ -9,7 +9,7 @@
9
9
 
10
10
  import { useState, useEffect, useMemo, useCallback } from "react";
11
11
  import { RouteParser } from "./RouteParser";
12
- import { getRouteNodeMetadata, loadRouteNode } from "./expoRouterStore";
12
+ import { getRouteNodeMetadata, isExpoRouterStoreSupported, loadRouteNode } from "./expoRouterStore";
13
13
 
14
14
  // Type-only definition to avoid Metro resolution issues
15
15
 
@@ -91,8 +91,12 @@ export function useRouteSitemap(options = {}) {
91
91
  searchQuery = "",
92
92
  sortBy = "path",
93
93
  autoRefresh = false,
94
- refreshInterval = 1000
94
+ refreshInterval = 1000,
95
+ injectedRoutes,
96
+ injectedSource = null,
97
+ injectedLastUpdatedAt = null
95
98
  } = options;
99
+ const hasInjectedRoutes = injectedRoutes != null;
96
100
  const [routeTreeState, setRouteTreeState] = useState(() => {
97
101
  const node = loadRouteNode();
98
102
  const metadata = getRouteNodeMetadata();
@@ -127,6 +131,16 @@ export function useRouteSitemap(options = {}) {
127
131
  if (routeNode) {
128
132
  return;
129
133
  }
134
+
135
+ // Routes injected from outside (dashboard) don't come from the local store.
136
+ if (hasInjectedRoutes) {
137
+ return;
138
+ }
139
+
140
+ // On web (no expo-router) the tree will never load — don't poll forever.
141
+ if (!isExpoRouterStoreSupported()) {
142
+ return;
143
+ }
130
144
  let retryCount = 0;
131
145
  const maxRetries = 100; // 10 seconds max
132
146
 
@@ -139,7 +153,7 @@ export function useRouteSitemap(options = {}) {
139
153
  };
140
154
  let timeoutRef = setTimeout(poll, 100);
141
155
  return () => clearTimeout(timeoutRef);
142
- }, [routeNode, refresh]);
156
+ }, [routeNode, refresh, hasInjectedRoutes]);
143
157
 
144
158
  // Optional auto-refresh hook for callers that want periodic updates
145
159
  useEffect(() => {
@@ -147,13 +161,19 @@ export function useRouteSitemap(options = {}) {
147
161
  const interval = setInterval(refresh, refreshInterval);
148
162
  return () => clearInterval(interval);
149
163
  }, [autoRefresh, refreshInterval, refresh]);
150
- const isLoaded = !!routeNode;
151
164
 
152
- // Parse routes
165
+ // With injected routes we're "supported" regardless of the local runtime, and
166
+ // "loaded" once the device has actually sent a non-empty tree (an empty array
167
+ // means the device is still booting expo-router → keep showing "Loading...").
168
+ const isLoaded = hasInjectedRoutes ? injectedRoutes.length > 0 : !!routeNode;
169
+ const isSupported = hasInjectedRoutes ? true : isExpoRouterStoreSupported();
170
+
171
+ // Parse routes (or use the pre-parsed routes injected from the dashboard).
153
172
  const routes = useMemo(() => {
173
+ if (hasInjectedRoutes) return injectedRoutes;
154
174
  if (!routeNode) return [];
155
175
  return RouteParser.parseRouteTree(routeNode);
156
- }, [routeNode, routeNodeVersion]);
176
+ }, [routeNode, routeNodeVersion, hasInjectedRoutes, injectedRoutes]);
157
177
 
158
178
  // Sort routes
159
179
  const sortedRoutes = useMemo(() => {
@@ -185,11 +205,12 @@ export function useRouteSitemap(options = {}) {
185
205
  stats,
186
206
  filteredRoutes,
187
207
  isLoaded,
208
+ isSupported,
188
209
  refresh,
189
210
  findRoute,
190
211
  getParents,
191
- lastUpdatedAt,
192
- source
212
+ lastUpdatedAt: hasInjectedRoutes ? injectedLastUpdatedAt : lastUpdatedAt,
213
+ source: hasInjectedRoutes ? injectedSource : source
193
214
  };
194
215
  }
195
216
 
@@ -1 +1 @@
1
- {"version":3,"file":"RouteTracker.d.ts","sourceRoot":"","sources":["../../src/RouteTracker.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAgBH,wBAAgB,YAAY,gCAM3B"}
1
+ {"version":3,"file":"RouteTracker.d.ts","sourceRoot":"","sources":["../../src/RouteTracker.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAgDH,wBAAgB,YAAY,gCAQ3B"}
@@ -4,8 +4,25 @@
4
4
  * Shows all screens currently mounted in memory, which one is visible,
5
5
  * and provides controls to manipulate the stack.
6
6
  */
7
+ import { type StackDisplayItem } from "../useNavigationStack";
8
+ /** Stack manipulation a host can be asked to perform on the device. */
9
+ export type NavigationStackActionType = "navigateToIndex" | "popToIndex" | "goBack" | "popToTop";
7
10
  export interface NavigationStackProps {
8
11
  style?: any;
12
+ /**
13
+ * Pre-captured stack supplied from outside the local runtime (the desktop
14
+ * dashboard receives it over the sync socket). When provided, the component
15
+ * renders this instead of reading the local navigation container.
16
+ */
17
+ injectedStack?: StackDisplayItem[];
18
+ /**
19
+ * Action delegate. When provided, stack actions (Back / Go / Pop To) call
20
+ * this instead of the local navigation container — the dashboard uses it to
21
+ * drive navigation on the connected device.
22
+ */
23
+ onAction?: (action: NavigationStackActionType, payload?: {
24
+ index?: number;
25
+ }) => void;
9
26
  }
10
- export declare function NavigationStack({ style }: NavigationStackProps): import("react").JSX.Element;
27
+ export declare function NavigationStack({ style, injectedStack, onAction, }: NavigationStackProps): import("react").JSX.Element;
11
28
  //# sourceMappingURL=NavigationStack.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"NavigationStack.d.ts","sourceRoot":"","sources":["../../../src/components/NavigationStack.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AA4BH,MAAM,WAAW,oBAAoB;IACnC,KAAK,CAAC,EAAE,GAAG,CAAC;CACb;AAMD,wBAAgB,eAAe,CAAC,EAAE,KAAK,EAAE,EAAE,oBAAoB,+BAya9D"}
1
+ {"version":3,"file":"NavigationStack.d.ts","sourceRoot":"","sources":["../../../src/components/NavigationStack.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAsBH,OAAO,EAEL,KAAK,gBAAgB,EACtB,MAAM,uBAAuB,CAAC;AAM/B,uEAAuE;AACvE,MAAM,MAAM,yBAAyB,GACjC,iBAAiB,GACjB,YAAY,GACZ,QAAQ,GACR,UAAU,CAAC;AAEf,MAAM,WAAW,oBAAoB;IACnC,KAAK,CAAC,EAAE,GAAG,CAAC;IAEZ;;;;OAIG;IACH,aAAa,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAEnC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,CACT,MAAM,EAAE,yBAAyB,EACjC,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,KACzB,IAAI,CAAC;CACX;AAMD,wBAAgB,eAAe,CAAC,EAC9B,KAAK,EACL,aAAa,EACb,QAAQ,GACT,EAAE,oBAAoB,+BAgctB"}
@@ -8,8 +8,26 @@
8
8
  * - Copy to clipboard
9
9
  * - Navigation
10
10
  */
11
+ import type { RouteInfo } from "../RouteParser";
11
12
  export interface RoutesSitemapProps {
12
13
  style?: any;
14
+ /**
15
+ * Pre-parsed route tree supplied from outside the local runtime (the desktop
16
+ * dashboard receives it over the sync socket). When provided, the component
17
+ * renders these routes instead of reading the local expo-router store.
18
+ */
19
+ injectedRoutes?: RouteInfo[];
20
+ /** Source label to display with injected routes. */
21
+ injectedSource?: "build" | "src" | null;
22
+ /** Last-updated timestamp to display with injected routes. */
23
+ injectedLastUpdatedAt?: number | null;
24
+ /**
25
+ * Navigation delegate. When provided, taps on a route call this instead of
26
+ * the local expo-router (the dashboard uses it to drive navigation on the
27
+ * connected device). The caller is responsible for any param resolution and
28
+ * Pro gating.
29
+ */
30
+ onNavigateRoute?: (route: RouteInfo) => void;
13
31
  }
14
- export declare function RoutesSitemap({ style }: RoutesSitemapProps): import("react").JSX.Element;
32
+ export declare function RoutesSitemap({ style, injectedRoutes, injectedSource, injectedLastUpdatedAt, onNavigateRoute, }: RoutesSitemapProps): import("react").JSX.Element;
15
33
  //# sourceMappingURL=RoutesSitemap.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"RoutesSitemap.d.ts","sourceRoot":"","sources":["../../../src/components/RoutesSitemap.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAgCH,MAAM,WAAW,kBAAkB;IACjC,KAAK,CAAC,EAAE,GAAG,CAAC;CACb;AAmBD,wBAAgB,aAAa,CAAC,EAAE,KAAK,EAAE,EAAE,kBAAkB,+BA2W1D"}
1
+ {"version":3,"file":"RoutesSitemap.d.ts","sourceRoot":"","sources":["../../../src/components/RoutesSitemap.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AA2BH,OAAO,KAAK,EAAE,SAAS,EAAc,MAAM,gBAAgB,CAAC;AAM5D,MAAM,WAAW,kBAAkB;IACjC,KAAK,CAAC,EAAE,GAAG,CAAC;IAEZ;;;;OAIG;IACH,cAAc,CAAC,EAAE,SAAS,EAAE,CAAC;IAE7B,oDAAoD;IACpD,cAAc,CAAC,EAAE,OAAO,GAAG,KAAK,GAAG,IAAI,CAAC;IAExC,8DAA8D;IAC9D,qBAAqB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAEtC;;;;;OAKG;IACH,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,CAAC;CAC9C;AAiCD,wBAAgB,aAAa,CAAC,EAC5B,KAAK,EACL,cAAc,EACd,cAAc,EACd,qBAAqB,EACrB,eAAe,GAChB,EAAE,kBAAkB,+BAwYpB"}
@@ -13,6 +13,14 @@ type ExpoRouterStore = {
13
13
  * The storeRef gets populated when Expo Router's useStore() hook runs.
14
14
  * So we cache the store reference but its property values update over time.
15
15
  */
16
+ /**
17
+ * Whether the expo-router store can be loaded in this runtime. The store is
18
+ * pulled in via CommonJS `require`, which only exists under Metro/Node. On the
19
+ * web (e.g. the desktop dashboard rendering these RN tools via react-native-web)
20
+ * `require` is undefined, the route tree lives on the device — not here — and
21
+ * there is nothing to load. Callers use this to skip polling/logging.
22
+ */
23
+ export declare function isExpoRouterStoreSupported(): boolean;
16
24
  export declare function getExpoRouterStore(): ExpoRouterStore | null;
17
25
  /**
18
26
  * Returns the current RouteNode tree (if available).
@@ -1 +1 @@
1
- {"version":3,"file":"expoRouterStore.d.ts","sourceRoot":"","sources":["../../src/expoRouterStore.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEzD,KAAK,eAAe,GAAG;IACrB,SAAS,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;IAC7B,aAAa,CAAC,EAAE;QACd,OAAO,CAAC,EAAE,MAAM,OAAO,CAAC;KACzB,CAAC;CACH,CAAC;AAmBF;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,IAAI,eAAe,GAAG,IAAI,CAkD3D;AAED;;;;GAIG;AACH,wBAAgB,aAAa,IAAI,SAAS,GAAG,IAAI,CAqBhD;AAED,wBAAgB,oBAAoB,IAAI;IACtC,MAAM,EAAE,OAAO,GAAG,KAAK,GAAG,IAAI,CAAC;IAC/B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B,CAKA"}
1
+ {"version":3,"file":"expoRouterStore.d.ts","sourceRoot":"","sources":["../../src/expoRouterStore.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEzD,KAAK,eAAe,GAAG;IACrB,SAAS,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;IAC7B,aAAa,CAAC,EAAE;QACd,OAAO,CAAC,EAAE,MAAM,OAAO,CAAC;KACzB,CAAC;CACH,CAAC;AAmBF;;;;;;;GAOG;AACH;;;;;;GAMG;AACH,wBAAgB,0BAA0B,IAAI,OAAO,CAEpD;AAED,wBAAgB,kBAAkB,IAAI,eAAe,GAAG,IAAI,CAwD3D;AAED;;;;GAIG;AACH,wBAAgB,aAAa,IAAI,SAAS,GAAG,IAAI,CAqBhD;AAED,wBAAgB,oBAAoB,IAAI;IACtC,MAAM,EAAE,OAAO,GAAG,KAAK,GAAG,IAAI,CAAC;IAC/B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B,CAKA"}
@@ -13,7 +13,7 @@ export { RouteTracker } from "./RouteTracker";
13
13
  export { RoutesSitemap } from "./components/RoutesSitemap";
14
14
  export type { RoutesSitemapProps } from "./components/RoutesSitemap";
15
15
  export { NavigationStack } from "./components/NavigationStack";
16
- export type { NavigationStackProps } from "./components/NavigationStack";
16
+ export type { NavigationStackProps, NavigationStackActionType, } from "./components/NavigationStack";
17
17
  export { RouteEventItemCompact } from "./components/RouteEventItemCompact";
18
18
  export type { RouteEventItemCompactProps } from "./components/RouteEventItemCompact";
19
19
  export { RouteEventExpandedContent } from "./components/RouteEventExpandedContent";
@@ -26,6 +26,8 @@ export { useRouteSitemap, useRoute, useParentRoutes } from "./useRouteSitemap";
26
26
  export type { UseRouteSitemapOptions, UseRouteSitemapResult, } from "./useRouteSitemap";
27
27
  export { useNavigationStack } from "./useNavigationStack";
28
28
  export type { UseNavigationStackResult, StackDisplayItem, } from "./useNavigationStack";
29
+ export { routeEventsSyncAdapter } from "./sync/routeEventsSyncAdapter";
30
+ export type { RouteSitemapSnapshot, RouteEventsSyncPayload, } from "./sync/routeEventsSyncAdapter";
29
31
  export type { RouteChangeEvent } from "./RouteObserver";
30
32
  export type { RouteInfo, RouteType, RouteGroup, RouteStats, } from "./RouteParser";
31
33
  export { RouteParser } from "./RouteParser";
@@ -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;AAKxE,OAAO,EAAE,wBAAwB,EAAE,MAAM,uCAAuC,CAAC;AACjF,YAAY,EAAE,6BAA6B,EAAE,MAAM,uCAAuC,CAAC;AAK3F,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAK9C,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,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACzE,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;AAK7F,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,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"}
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;AAKxE,OAAO,EAAE,wBAAwB,EAAE,MAAM,uCAAuC,CAAC;AACjF,YAAY,EAAE,6BAA6B,EAAE,MAAM,uCAAuC,CAAC;AAK3F,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAK9C,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;AAK7F,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"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Navigation Stack Store
3
+ *
4
+ * Holds the latest serializable navigation stack plus references to the live
5
+ * navigation action functions. The stack is captured inside the navigation tree
6
+ * by <RouteTracker /> (which runs useNavigationStack), and read by the
7
+ * route-events sync adapter so the dashboard can render the Stack tab and drive
8
+ * navigation on the device remotely.
9
+ *
10
+ * The stack itself (StackDisplayItem[]) is JSON-serializable and synced to the
11
+ * dashboard. The action functions are NOT serialized — they stay on the device
12
+ * and are invoked when the dashboard sends a remote action.
13
+ */
14
+ import type { StackDisplayItem } from "../useNavigationStack";
15
+ export interface NavigationStackActions {
16
+ navigateToIndex: (index: number) => void;
17
+ popToIndex: (index: number) => void;
18
+ goBack: () => void;
19
+ popToTop: () => void;
20
+ }
21
+ declare class NavigationStackStore {
22
+ private stack;
23
+ private actions;
24
+ private listeners;
25
+ getStack(): StackDisplayItem[];
26
+ setStack(stack: StackDisplayItem[]): void;
27
+ getActions(): NavigationStackActions | null;
28
+ setActions(actions: NavigationStackActions | null): void;
29
+ subscribe(listener: () => void): () => void;
30
+ }
31
+ export declare const navigationStackStore: NavigationStackStore;
32
+ export {};
33
+ //# sourceMappingURL=navigationStackStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"navigationStackStore.d.ts","sourceRoot":"","sources":["../../../src/stores/navigationStackStore.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,MAAM,WAAW,sBAAsB;IACrC,eAAe,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,UAAU,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,cAAM,oBAAoB;IACxB,OAAO,CAAC,KAAK,CAA0B;IACvC,OAAO,CAAC,OAAO,CAAuC;IACtD,OAAO,CAAC,SAAS,CAAyB;IAE1C,QAAQ,IAAI,gBAAgB,EAAE;IAI9B,QAAQ,CAAC,KAAK,EAAE,gBAAgB,EAAE,GAAG,IAAI;IAKzC,UAAU,IAAI,sBAAsB,GAAG,IAAI;IAI3C,UAAU,CAAC,OAAO,EAAE,sBAAsB,GAAG,IAAI,GAAG,IAAI;IAIxD,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI;CAM5C;AAED,eAAO,MAAM,oBAAoB,sBAA6B,CAAC"}
@@ -0,0 +1,69 @@
1
+ import { type RouteInfo } from "../RouteParser";
2
+ import type { RouteChangeEvent } from "../RouteObserver";
3
+ import type { StackDisplayItem } from "../useNavigationStack";
4
+ /**
5
+ * Serializable snapshot of the device's route tree, sent to the dashboard so
6
+ * the Routes tab can render a sitemap (the raw expo-router RouteNode itself is
7
+ * not JSON-serializable — it holds components/functions — so we send the parsed
8
+ * RouteInfo[] instead).
9
+ */
10
+ export interface RouteSitemapSnapshot {
11
+ /** Parsed, nested route tree (same shape useRouteSitemap parses locally). */
12
+ routes: RouteInfo[];
13
+ /** Which expo-router path provided the store ("build" | "src"). */
14
+ source: "build" | "src" | null;
15
+ /** Timestamp of the most recent successful route-tree read on the device. */
16
+ lastUpdatedAt: number | null;
17
+ }
18
+ /**
19
+ * Payload shape for the route-events tool (adapter version 3). Consumers must
20
+ * tolerate older shapes: v1 sends a bare RouteChangeEvent[]; v2 omits `stack`.
21
+ */
22
+ export interface RouteEventsSyncPayload {
23
+ events: RouteChangeEvent[];
24
+ sitemap: RouteSitemapSnapshot;
25
+ /** Live navigation stack (top-most last). Empty until a stack is captured. */
26
+ stack: StackDisplayItem[];
27
+ }
28
+ /**
29
+ * Sync adapter for the route-events tool, consumed by @buoy-gg/external-sync's
30
+ * `useExternalSync` (structurally matches its ToolSyncAdapter interface so
31
+ * this package doesn't need a dependency on it).
32
+ *
33
+ * Subscribing attaches the routeObserver listener, so route changes are only
34
+ * recorded while a dashboard is watching. (Route events still require a
35
+ * <RouteTracker /> inside the navigation tree to be emitted at all.)
36
+ *
37
+ * The snapshot carries both the route-change events AND the parsed route
38
+ * sitemap, so the dashboard — which has no local expo-router store — can render
39
+ * the route tree. The `navigate` action lets the dashboard drive navigation on
40
+ * the device.
41
+ */
42
+ export declare const routeEventsSyncAdapter: {
43
+ version: number;
44
+ getSnapshot: () => RouteEventsSyncPayload;
45
+ subscribe: (onChange: () => void) => () => void;
46
+ actions: {
47
+ clearEvents: () => void;
48
+ /**
49
+ * Navigate the device to a concrete path. The dashboard resolves any
50
+ * dynamic params into a concrete path before invoking this.
51
+ */
52
+ navigate: (params: unknown) => {
53
+ navigated: string;
54
+ };
55
+ stackNavigateToIndex: (params: unknown) => {
56
+ navigatedToIndex: number;
57
+ };
58
+ stackPopToIndex: (params: unknown) => {
59
+ poppedToIndex: number;
60
+ };
61
+ stackGoBack: () => {
62
+ wentBack: boolean;
63
+ };
64
+ stackPopToTop: () => {
65
+ poppedToTop: boolean;
66
+ };
67
+ };
68
+ };
69
+ //# sourceMappingURL=routeEventsSyncAdapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routeEventsSyncAdapter.d.ts","sourceRoot":"","sources":["../../../src/sync/routeEventsSyncAdapter.ts"],"names":[],"mappings":"AAGA,OAAO,EAAe,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE9D;;;;;GAKG;AACH,MAAM,WAAW,oBAAoB;IACnC,6EAA6E;IAC7E,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,mEAAmE;IACnE,MAAM,EAAE,OAAO,GAAG,KAAK,GAAG,IAAI,CAAC;IAC/B,6EAA6E;IAC7E,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED;;;GAGG;AACH,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,gBAAgB,EAAE,CAAC;IAC3B,OAAO,EAAE,oBAAoB,CAAC;IAC9B,8EAA8E;IAC9E,KAAK,EAAE,gBAAgB,EAAE,CAAC;CAC3B;AAWD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,sBAAsB;;uBAEhB,sBAAsB;0BAKjB,MAAM,IAAI;;;QAkC9B;;;WAGG;2BACgB,OAAO;;;uCAcK,OAAO;;;kCAUZ,OAAO;;;;;;;;;;CAuBpC,CAAC"}
@@ -24,6 +24,18 @@ export interface UseRouteSitemapOptions {
24
24
  * @default 1000
25
25
  */
26
26
  refreshInterval?: number;
27
+ /**
28
+ * Pre-parsed routes supplied from outside the local runtime (e.g. the desktop
29
+ * dashboard, which receives the device's route tree over the sync socket
30
+ * rather than reading expo-router directly). When provided, the local
31
+ * expo-router store is ignored: these routes drive the sort/filter/group/stats
32
+ * pipeline and `isSupported` is forced true.
33
+ */
34
+ injectedRoutes?: RouteInfo[];
35
+ /** Source label to surface alongside injected routes. */
36
+ injectedSource?: "build" | "src" | null;
37
+ /** Last-updated timestamp to surface alongside injected routes. */
38
+ injectedLastUpdatedAt?: number | null;
27
39
  }
28
40
  export interface UseRouteSitemapResult {
29
41
  /**
@@ -46,6 +58,11 @@ export interface UseRouteSitemapResult {
46
58
  * Is route data loaded
47
59
  */
48
60
  isLoaded: boolean;
61
+ /**
62
+ * Whether the route sitemap can be read in this runtime at all. False on the
63
+ * web/dashboard, where the route tree lives on the device rather than locally.
64
+ */
65
+ isSupported: boolean;
49
66
  /**
50
67
  * Manually refresh route data
51
68
  */
@@ -1 +1 @@
1
- {"version":3,"file":"useRouteSitemap.d.ts","sourceRoot":"","sources":["../../src/useRouteSitemap.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAEL,KAAK,SAAS,EACd,KAAK,UAAU,EACf,KAAK,UAAU,EAChB,MAAM,eAAe,CAAC;AAoEvB,MAAM,WAAW,sBAAsB;IACrC;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;IAElC;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,qBAAqB;IACpC;;OAEG;IACH,MAAM,EAAE,SAAS,EAAE,CAAC;IAEpB;;OAEG;IACH,MAAM,EAAE,UAAU,EAAE,CAAC;IAErB;;OAEG;IACH,KAAK,EAAE,UAAU,CAAC;IAElB;;OAEG;IACH,cAAc,EAAE,SAAS,EAAE,CAAC;IAE5B;;OAEG;IACH,QAAQ,EAAE,OAAO,CAAC;IAElB;;OAEG;IACH,OAAO,EAAE,MAAM,IAAI,CAAC;IAEpB;;OAEG;IACH,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,SAAS,GAAG,IAAI,CAAC;IAE9C;;OAEG;IACH,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,SAAS,EAAE,CAAC;IAE1C;;OAEG;IACH,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAE7B;;OAEG;IACH,MAAM,EAAE,OAAO,GAAG,KAAK,GAAG,IAAI,CAAC;CAChC;AAMD;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAC7B,OAAO,GAAE,sBAA2B,GACnC,qBAAqB,CAuHvB;AAMD;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAGvD;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,CAGzD"}
1
+ {"version":3,"file":"useRouteSitemap.d.ts","sourceRoot":"","sources":["../../src/useRouteSitemap.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAEL,KAAK,SAAS,EACd,KAAK,UAAU,EACf,KAAK,UAAU,EAChB,MAAM,eAAe,CAAC;AAwEvB,MAAM,WAAW,sBAAsB;IACrC;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;IAElC;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,SAAS,EAAE,CAAC;IAE7B,yDAAyD;IACzD,cAAc,CAAC,EAAE,OAAO,GAAG,KAAK,GAAG,IAAI,CAAC;IAExC,mEAAmE;IACnE,qBAAqB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACvC;AAED,MAAM,WAAW,qBAAqB;IACpC;;OAEG;IACH,MAAM,EAAE,SAAS,EAAE,CAAC;IAEpB;;OAEG;IACH,MAAM,EAAE,UAAU,EAAE,CAAC;IAErB;;OAEG;IACH,KAAK,EAAE,UAAU,CAAC;IAElB;;OAEG;IACH,cAAc,EAAE,SAAS,EAAE,CAAC;IAE5B;;OAEG;IACH,QAAQ,EAAE,OAAO,CAAC;IAElB;;;OAGG;IACH,WAAW,EAAE,OAAO,CAAC;IAErB;;OAEG;IACH,OAAO,EAAE,MAAM,IAAI,CAAC;IAEpB;;OAEG;IACH,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,SAAS,GAAG,IAAI,CAAC;IAE9C;;OAEG;IACH,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,SAAS,EAAE,CAAC;IAE1C;;OAEG;IACH,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAE7B;;OAEG;IACH,MAAM,EAAE,OAAO,GAAG,KAAK,GAAG,IAAI,CAAC;CAChC;AAMD;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAC7B,OAAO,GAAE,sBAA2B,GACnC,qBAAqB,CA4IvB;AAMD;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAGvD;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,CAGzD"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@buoy-gg/route-events",
3
- "version": "3.0.1",
3
+ "version": "3.0.2",
4
4
  "description": "route-events package",
5
5
  "main": "lib/commonjs/index.js",
6
6
  "module": "lib/module/index.js",
@@ -26,11 +26,11 @@
26
26
  ],
27
27
  "sideEffects": false,
28
28
  "dependencies": {
29
- "@buoy-gg/floating-tools-core": "3.0.1",
30
- "@buoy-gg/shared-ui": "3.0.1"
29
+ "@buoy-gg/floating-tools-core": "3.0.2",
30
+ "@buoy-gg/shared-ui": "3.0.2"
31
31
  },
32
32
  "peerDependencies": {
33
- "@buoy-gg/license": "3.0.1",
33
+ "@buoy-gg/license": "3.0.2",
34
34
  "@react-native-async-storage/async-storage": "*",
35
35
  "@react-navigation/native": "*",
36
36
  "expo-router": "*",
@@ -49,7 +49,7 @@
49
49
  "@types/react-native": "^0.73.0",
50
50
  "expo-router": "~5.0.7",
51
51
  "typescript": "~5.8.3",
52
- "@buoy-gg/license": "3.0.1"
52
+ "@buoy-gg/license": "3.0.2"
53
53
  },
54
54
  "react-native-builder-bob": {
55
55
  "source": "src",