@buoy-gg/route-events 1.7.8 → 2.1.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.
@@ -28,7 +28,7 @@ function RouteEventDetailContent({
28
28
  const loadPreferences = async () => {
29
29
  try {
30
30
  // Load detail view preference (current/diff)
31
- const savedDetailView = await (0, _sharedUi.safeGetItem)(_sharedUi.devToolsStorageKeys.routeEvents.detailView());
31
+ const savedDetailView = await _sharedUi.persistentStorage.getItem(_sharedUi.devToolsStorageKeys.routeEvents.detailView());
32
32
  if (savedDetailView === "current" || savedDetailView === "diff") {
33
33
  setInternalActiveView(savedDetailView);
34
34
  }
@@ -44,7 +44,7 @@ function RouteEventDetailContent({
44
44
  const handleViewChange = (0, _react.useCallback)(async view => {
45
45
  setInternalActiveView(view);
46
46
  try {
47
- await (0, _sharedUi.safeSetItem)(_sharedUi.devToolsStorageKeys.routeEvents.detailView(), view);
47
+ await _sharedUi.persistentStorage.setItem(_sharedUi.devToolsStorageKeys.routeEvents.detailView(), view);
48
48
  } catch (error) {
49
49
  // Failed to save detail view preference
50
50
  }
@@ -12,7 +12,7 @@ var _jsxRuntime = require("react/jsx-runtime");
12
12
  /**
13
13
  * RouteEventItemCompact - Compact list item for route events
14
14
  *
15
- * Uses CompactRow pattern matching network/storage components
15
+ * Uses CompactRow pattern matching network/storage/redux components
16
16
  */
17
17
 
18
18
  // Route type for color coding
@@ -53,16 +53,13 @@ function getRouteTypeColor(routeType) {
53
53
  switch (routeType) {
54
54
  case "home":
55
55
  return _sharedUi.buoyColors.success;
56
- // Teal
57
56
  case "dynamic":
58
57
  return _sharedUi.buoyColors.primary;
59
- // Teal
60
58
  case "with-params":
61
59
  return _sharedUi.buoyColors.warning;
62
- // Orange
63
60
  default:
64
- return _sharedUi.buoyColors.border;
65
- // Gray
61
+ return _sharedUi.buoyColors.textSecondary;
62
+ // More visible than border color
66
63
  }
67
64
  }
68
65
 
@@ -80,15 +77,42 @@ function getStatusLabel(routeType) {
80
77
  }
81
78
  }
82
79
 
83
- // Get secondary text (param count + route type)
84
- function getSecondaryText(event, routeType) {
80
+ // Format duration in human-readable format
81
+ function formatDuration(ms) {
82
+ if (ms < 1000) return `${Math.round(ms)}ms`;
83
+ if (ms < 60000) return `${(ms / 1000).toFixed(1)}s`;
84
+ const minutes = Math.floor(ms / 60000);
85
+ const seconds = Math.floor(ms % 60000 / 1000);
86
+ return seconds > 0 ? `${minutes}m ${seconds}s` : `${minutes}m`;
87
+ }
88
+
89
+ // Get status sublabel (time on previous route + depth info)
90
+ function getStatusSublabel(event) {
91
+ const parts = [];
92
+
93
+ // Show time spent on previous route if available
94
+ if (event.timeSincePrevious !== undefined && event.timeSincePrevious > 0) {
95
+ parts.push(formatDuration(event.timeSincePrevious));
96
+ }
97
+
98
+ // Show segment depth (e.g., "depth 2" for /users/profile)
99
+ const depth = event.segments?.length || 0;
100
+ if (depth > 0) {
101
+ parts.push(`depth ${depth}`);
102
+ }
103
+ return parts.join(" · ") || "root";
104
+ }
105
+
106
+ // Get badge text - only show when there's additional info beyond the status label
107
+ function getBadgeText(event) {
85
108
  const hasParams = event.params && Object.keys(event.params).length > 0;
86
- if (!hasParams) {
87
- return undefined;
109
+ if (hasParams) {
110
+ const paramCount = Object.keys(event.params).length;
111
+ return `${paramCount} PARAM${paramCount !== 1 ? "S" : ""}`;
88
112
  }
89
- const paramCount = Object.keys(event.params).length;
90
- const paramText = `${paramCount} param${paramCount !== 1 ? 's' : ''}`;
91
- return `${paramText} • ${getStatusLabel(routeType)}`;
113
+
114
+ // Don't show badge text - route type is already shown in status label
115
+ return undefined;
92
116
  }
93
117
  function RouteEventItemCompact({
94
118
  event,
@@ -101,7 +125,8 @@ function RouteEventItemCompact({
101
125
  const routeTemplate = (0, _react.useMemo)(() => getRouteTemplate(event.pathname, event.segments), [event.pathname, event.segments]);
102
126
  const statusColor = (0, _react.useMemo)(() => getRouteTypeColor(routeType), [routeType]);
103
127
  const statusLabel = (0, _react.useMemo)(() => getStatusLabel(routeType), [routeType]);
104
- const secondaryText = (0, _react.useMemo)(() => getSecondaryText(event, routeType), [event, routeType]);
128
+ const statusSublabel = (0, _react.useMemo)(() => getStatusSublabel(event), [event]);
129
+ const badgeText = (0, _react.useMemo)(() => getBadgeText(event), [event]);
105
130
  const timeLabel = (0, _react.useMemo)(() => (0, _sharedUi.formatRelativeTime)(new Date(event.timestamp)), [event.timestamp]);
106
131
  const expandedContent = (0, _react.useMemo)(() => {
107
132
  if (!isExpanded) return undefined;
@@ -111,18 +136,17 @@ function RouteEventItemCompact({
111
136
  routeTemplate: routeTemplate
112
137
  });
113
138
  }, [isExpanded, event, visitNumber, routeTemplate]);
139
+
140
+ // Custom badge shows Go button (and badge text if present) when onNavigate is provided
114
141
  const customBadge = (0, _react.useMemo)(() => {
115
- if (!onNavigate) {
116
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
117
- style: styles.timeText,
118
- children: timeLabel
119
- });
120
- }
142
+ if (!onNavigate) return undefined;
121
143
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
122
144
  style: styles.badgeContainer,
123
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
124
- style: styles.timeText,
125
- children: timeLabel
145
+ children: [badgeText && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
146
+ style: [styles.badgeText, {
147
+ color: statusColor
148
+ }],
149
+ children: badgeText
126
150
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
127
151
  style: styles.goButton,
128
152
  onPress: e => {
@@ -135,13 +159,18 @@ function RouteEventItemCompact({
135
159
  })
136
160
  })]
137
161
  });
138
- }, [timeLabel, onNavigate, event.pathname]);
162
+ }, [onNavigate, event.pathname, badgeText, statusColor]);
139
163
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.CompactRow, {
140
164
  statusDotColor: statusColor,
141
165
  statusLabel: statusLabel,
142
- primaryText: event.pathname,
143
- secondaryText: secondaryText,
166
+ statusSublabel: statusSublabel,
167
+ primaryText: event.pathname
168
+ // Use badgeText when no customBadge, otherwise badge is inside customBadge
169
+ ,
170
+ badgeText: onNavigate ? undefined : badgeText,
171
+ badgeColor: statusColor,
144
172
  customBadge: customBadge,
173
+ bottomRightText: timeLabel,
145
174
  showChevron: true,
146
175
  expandedContent: expandedContent,
147
176
  isExpanded: isExpanded,
@@ -155,9 +184,9 @@ const styles = _reactNative.StyleSheet.create({
155
184
  alignItems: "center",
156
185
  gap: 6
157
186
  },
158
- timeText: {
159
- fontSize: 10,
160
- color: _sharedUi.buoyColors.textMuted,
187
+ badgeText: {
188
+ fontSize: 11,
189
+ fontWeight: "600",
161
190
  fontFamily: "monospace"
162
191
  },
163
192
  goButton: {
@@ -69,7 +69,7 @@ function RouteEventsModalWithTabs({
69
69
  if (!visible || hasLoadedTabState.current) return;
70
70
  const loadTabState = async () => {
71
71
  try {
72
- const storedTab = await (0, _sharedUi.safeGetItem)(_sharedUi.devToolsStorageKeys.routeEvents.activeTab());
72
+ const storedTab = await _sharedUi.persistentStorage.getItem(_sharedUi.devToolsStorageKeys.routeEvents.activeTab());
73
73
  if (storedTab && (storedTab === "routes" || storedTab === "events")) {
74
74
  setActiveTab(storedTab);
75
75
  }
@@ -86,7 +86,7 @@ function RouteEventsModalWithTabs({
86
86
  if (!visible || hasLoadedMonitoringState.current) return;
87
87
  const loadMonitoringState = async () => {
88
88
  try {
89
- const storedMonitoring = await (0, _sharedUi.safeGetItem)(_sharedUi.devToolsStorageKeys.routeEvents.isMonitoring());
89
+ const storedMonitoring = await _sharedUi.persistentStorage.getItem(_sharedUi.devToolsStorageKeys.routeEvents.isMonitoring());
90
90
  if (storedMonitoring !== null) {
91
91
  const shouldMonitor = storedMonitoring === "true";
92
92
  setIsListening(shouldMonitor);
@@ -104,7 +104,7 @@ function RouteEventsModalWithTabs({
104
104
  if (!hasLoadedTabState.current) return;
105
105
  const saveTabState = async () => {
106
106
  try {
107
- await (0, _sharedUi.safeSetItem)(_sharedUi.devToolsStorageKeys.routeEvents.activeTab(), activeTab);
107
+ await _sharedUi.persistentStorage.setItem(_sharedUi.devToolsStorageKeys.routeEvents.activeTab(), activeTab);
108
108
  } catch (error) {
109
109
  // Failed to save tab state
110
110
  }
@@ -117,7 +117,7 @@ function RouteEventsModalWithTabs({
117
117
  if (!hasLoadedMonitoringState.current) return;
118
118
  const saveMonitoringState = async () => {
119
119
  try {
120
- await (0, _sharedUi.safeSetItem)(_sharedUi.devToolsStorageKeys.routeEvents.isMonitoring(), isListening.toString());
120
+ await _sharedUi.persistentStorage.setItem(_sharedUi.devToolsStorageKeys.routeEvents.isMonitoring(), isListening.toString());
121
121
  } catch (error) {
122
122
  // Failed to save monitoring state
123
123
  }
@@ -130,7 +130,7 @@ function RouteEventsModalWithTabs({
130
130
  if (!visible || hasLoadedFilters.current) return;
131
131
  const loadFilters = async () => {
132
132
  try {
133
- const storedFilters = await (0, _sharedUi.safeGetItem)(_sharedUi.devToolsStorageKeys.routeEvents.eventFilters());
133
+ const storedFilters = await _sharedUi.persistentStorage.getItem(_sharedUi.devToolsStorageKeys.routeEvents.eventFilters());
134
134
  if (storedFilters) {
135
135
  const filters = JSON.parse(storedFilters);
136
136
  setIgnoredPatterns(new Set(filters));
@@ -149,7 +149,7 @@ function RouteEventsModalWithTabs({
149
149
  const saveFilters = async () => {
150
150
  try {
151
151
  const filters = Array.from(ignoredPatterns);
152
- await (0, _sharedUi.safeSetItem)(_sharedUi.devToolsStorageKeys.routeEvents.eventFilters(), JSON.stringify(filters));
152
+ await _sharedUi.persistentStorage.setItem(_sharedUi.devToolsStorageKeys.routeEvents.eventFilters(), JSON.stringify(filters));
153
153
  } catch (error) {
154
154
  // Failed to save filters
155
155
  }
@@ -9,6 +9,18 @@ Object.defineProperty(exports, "NavigationStack", {
9
9
  return _NavigationStack.NavigationStack;
10
10
  }
11
11
  });
12
+ Object.defineProperty(exports, "RouteEventExpandedContent", {
13
+ enumerable: true,
14
+ get: function () {
15
+ return _RouteEventExpandedContent.RouteEventExpandedContent;
16
+ }
17
+ });
18
+ Object.defineProperty(exports, "RouteEventItemCompact", {
19
+ enumerable: true,
20
+ get: function () {
21
+ return _RouteEventItemCompact.RouteEventItemCompact;
22
+ }
23
+ });
12
24
  Object.defineProperty(exports, "RouteEventsModalWithTabs", {
13
25
  enumerable: true,
14
26
  get: function () {
@@ -87,13 +99,15 @@ Object.defineProperty(exports, "useRouteSitemap", {
87
99
  return _useRouteSitemap.useRouteSitemap;
88
100
  }
89
101
  });
90
- var _RouteEventsModalWithTabs = require("./components/RouteEventsModalWithTabs");
91
102
  var _preset = require("./preset");
103
+ var _RouteEventsModalWithTabs = require("./components/RouteEventsModalWithTabs");
92
104
  var _RouteTracker = require("./RouteTracker");
93
105
  var _RoutesSitemap = require("./components/RoutesSitemap");
94
106
  var _NavigationStack = require("./components/NavigationStack");
95
- var _RouteObserver = require("./RouteObserver");
107
+ var _RouteEventItemCompact = require("./components/RouteEventItemCompact");
108
+ var _RouteEventExpandedContent = require("./components/RouteEventExpandedContent");
96
109
  var _useRouteObserver = require("./useRouteObserver");
97
- var _RouteParser = require("./RouteParser");
98
110
  var _useRouteSitemap = require("./useRouteSitemap");
99
- var _useNavigationStack = require("./useNavigationStack");
111
+ var _useNavigationStack = require("./useNavigationStack");
112
+ var _RouteParser = require("./RouteParser");
113
+ var _RouteObserver = require("./RouteObserver");
@@ -2,7 +2,7 @@
2
2
 
3
3
  import { View, Text, StyleSheet, TouchableOpacity, ScrollView } from "react-native";
4
4
  import { useEffect, useState, useCallback, useRef } from "react";
5
- import { formatRelativeTime, devToolsStorageKeys, ChevronLeft, ChevronRight, AlertCircle, Navigation as NavigationIcon, GitBranch, safeGetItem, safeSetItem, buoyColors } from "@buoy-gg/shared-ui";
5
+ import { formatRelativeTime, devToolsStorageKeys, ChevronLeft, ChevronRight, AlertCircle, Navigation as NavigationIcon, GitBranch, persistentStorage, buoyColors } from "@buoy-gg/shared-ui";
6
6
  import { DataViewer } from "@buoy-gg/shared-ui/dataViewer";
7
7
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
8
8
  export function RouteEventDetailContent({
@@ -23,7 +23,7 @@ export function RouteEventDetailContent({
23
23
  const loadPreferences = async () => {
24
24
  try {
25
25
  // Load detail view preference (current/diff)
26
- const savedDetailView = await safeGetItem(devToolsStorageKeys.routeEvents.detailView());
26
+ const savedDetailView = await persistentStorage.getItem(devToolsStorageKeys.routeEvents.detailView());
27
27
  if (savedDetailView === "current" || savedDetailView === "diff") {
28
28
  setInternalActiveView(savedDetailView);
29
29
  }
@@ -39,7 +39,7 @@ export function RouteEventDetailContent({
39
39
  const handleViewChange = useCallback(async view => {
40
40
  setInternalActiveView(view);
41
41
  try {
42
- await safeSetItem(devToolsStorageKeys.routeEvents.detailView(), view);
42
+ await persistentStorage.setItem(devToolsStorageKeys.routeEvents.detailView(), view);
43
43
  } catch (error) {
44
44
  // Failed to save detail view preference
45
45
  }
@@ -3,7 +3,7 @@
3
3
  /**
4
4
  * RouteEventItemCompact - Compact list item for route events
5
5
  *
6
- * Uses CompactRow pattern matching network/storage components
6
+ * Uses CompactRow pattern matching network/storage/redux components
7
7
  */
8
8
 
9
9
  import { useMemo } from "react";
@@ -49,16 +49,13 @@ function getRouteTypeColor(routeType) {
49
49
  switch (routeType) {
50
50
  case "home":
51
51
  return buoyColors.success;
52
- // Teal
53
52
  case "dynamic":
54
53
  return buoyColors.primary;
55
- // Teal
56
54
  case "with-params":
57
55
  return buoyColors.warning;
58
- // Orange
59
56
  default:
60
- return buoyColors.border;
61
- // Gray
57
+ return buoyColors.textSecondary;
58
+ // More visible than border color
62
59
  }
63
60
  }
64
61
 
@@ -76,15 +73,42 @@ function getStatusLabel(routeType) {
76
73
  }
77
74
  }
78
75
 
79
- // Get secondary text (param count + route type)
80
- function getSecondaryText(event, routeType) {
76
+ // Format duration in human-readable format
77
+ function formatDuration(ms) {
78
+ if (ms < 1000) return `${Math.round(ms)}ms`;
79
+ if (ms < 60000) return `${(ms / 1000).toFixed(1)}s`;
80
+ const minutes = Math.floor(ms / 60000);
81
+ const seconds = Math.floor(ms % 60000 / 1000);
82
+ return seconds > 0 ? `${minutes}m ${seconds}s` : `${minutes}m`;
83
+ }
84
+
85
+ // Get status sublabel (time on previous route + depth info)
86
+ function getStatusSublabel(event) {
87
+ const parts = [];
88
+
89
+ // Show time spent on previous route if available
90
+ if (event.timeSincePrevious !== undefined && event.timeSincePrevious > 0) {
91
+ parts.push(formatDuration(event.timeSincePrevious));
92
+ }
93
+
94
+ // Show segment depth (e.g., "depth 2" for /users/profile)
95
+ const depth = event.segments?.length || 0;
96
+ if (depth > 0) {
97
+ parts.push(`depth ${depth}`);
98
+ }
99
+ return parts.join(" · ") || "root";
100
+ }
101
+
102
+ // Get badge text - only show when there's additional info beyond the status label
103
+ function getBadgeText(event) {
81
104
  const hasParams = event.params && Object.keys(event.params).length > 0;
82
- if (!hasParams) {
83
- return undefined;
105
+ if (hasParams) {
106
+ const paramCount = Object.keys(event.params).length;
107
+ return `${paramCount} PARAM${paramCount !== 1 ? "S" : ""}`;
84
108
  }
85
- const paramCount = Object.keys(event.params).length;
86
- const paramText = `${paramCount} param${paramCount !== 1 ? 's' : ''}`;
87
- return `${paramText} • ${getStatusLabel(routeType)}`;
109
+
110
+ // Don't show badge text - route type is already shown in status label
111
+ return undefined;
88
112
  }
89
113
  export function RouteEventItemCompact({
90
114
  event,
@@ -97,7 +121,8 @@ export function RouteEventItemCompact({
97
121
  const routeTemplate = useMemo(() => getRouteTemplate(event.pathname, event.segments), [event.pathname, event.segments]);
98
122
  const statusColor = useMemo(() => getRouteTypeColor(routeType), [routeType]);
99
123
  const statusLabel = useMemo(() => getStatusLabel(routeType), [routeType]);
100
- const secondaryText = useMemo(() => getSecondaryText(event, routeType), [event, routeType]);
124
+ const statusSublabel = useMemo(() => getStatusSublabel(event), [event]);
125
+ const badgeText = useMemo(() => getBadgeText(event), [event]);
101
126
  const timeLabel = useMemo(() => formatRelativeTime(new Date(event.timestamp)), [event.timestamp]);
102
127
  const expandedContent = useMemo(() => {
103
128
  if (!isExpanded) return undefined;
@@ -107,18 +132,17 @@ export function RouteEventItemCompact({
107
132
  routeTemplate: routeTemplate
108
133
  });
109
134
  }, [isExpanded, event, visitNumber, routeTemplate]);
135
+
136
+ // Custom badge shows Go button (and badge text if present) when onNavigate is provided
110
137
  const customBadge = useMemo(() => {
111
- if (!onNavigate) {
112
- return /*#__PURE__*/_jsx(Text, {
113
- style: styles.timeText,
114
- children: timeLabel
115
- });
116
- }
138
+ if (!onNavigate) return undefined;
117
139
  return /*#__PURE__*/_jsxs(View, {
118
140
  style: styles.badgeContainer,
119
- children: [/*#__PURE__*/_jsx(Text, {
120
- style: styles.timeText,
121
- children: timeLabel
141
+ children: [badgeText && /*#__PURE__*/_jsx(Text, {
142
+ style: [styles.badgeText, {
143
+ color: statusColor
144
+ }],
145
+ children: badgeText
122
146
  }), /*#__PURE__*/_jsx(TouchableOpacity, {
123
147
  style: styles.goButton,
124
148
  onPress: e => {
@@ -131,13 +155,18 @@ export function RouteEventItemCompact({
131
155
  })
132
156
  })]
133
157
  });
134
- }, [timeLabel, onNavigate, event.pathname]);
158
+ }, [onNavigate, event.pathname, badgeText, statusColor]);
135
159
  return /*#__PURE__*/_jsx(CompactRow, {
136
160
  statusDotColor: statusColor,
137
161
  statusLabel: statusLabel,
138
- primaryText: event.pathname,
139
- secondaryText: secondaryText,
162
+ statusSublabel: statusSublabel,
163
+ primaryText: event.pathname
164
+ // Use badgeText when no customBadge, otherwise badge is inside customBadge
165
+ ,
166
+ badgeText: onNavigate ? undefined : badgeText,
167
+ badgeColor: statusColor,
140
168
  customBadge: customBadge,
169
+ bottomRightText: timeLabel,
141
170
  showChevron: true,
142
171
  expandedContent: expandedContent,
143
172
  isExpanded: isExpanded,
@@ -151,9 +180,9 @@ const styles = StyleSheet.create({
151
180
  alignItems: "center",
152
181
  gap: 6
153
182
  },
154
- timeText: {
155
- fontSize: 10,
156
- color: buoyColors.textMuted,
183
+ badgeText: {
184
+ fontSize: 11,
185
+ fontWeight: "600",
157
186
  fontFamily: "monospace"
158
187
  },
159
188
  goButton: {
@@ -3,7 +3,7 @@
3
3
  import { useState, useCallback, useEffect, useRef, useMemo } from "react";
4
4
  import { Text, View, TouchableOpacity, StyleSheet, Alert } from "react-native";
5
5
  import { useRouter } from "expo-router";
6
- import { JsModal, ModalHeader, TabSelector, formatRelativeTime, devToolsStorageKeys, Navigation, Pause, Play, Trash2, Filter, SearchBar, safeGetItem, safeSetItem, ToolbarCopyButton, Lock, ProUpgradeModal, buoyColors } from "@buoy-gg/shared-ui";
6
+ import { JsModal, ModalHeader, TabSelector, formatRelativeTime, devToolsStorageKeys, Navigation, Pause, Play, Trash2, Filter, SearchBar, persistentStorage, ToolbarCopyButton, Lock, ProUpgradeModal, buoyColors } from "@buoy-gg/shared-ui";
7
7
  import { useIsPro } from "@buoy-gg/license";
8
8
 
9
9
  // Free tier limit for route events
@@ -66,7 +66,7 @@ export function RouteEventsModalWithTabs({
66
66
  if (!visible || hasLoadedTabState.current) return;
67
67
  const loadTabState = async () => {
68
68
  try {
69
- const storedTab = await safeGetItem(devToolsStorageKeys.routeEvents.activeTab());
69
+ const storedTab = await persistentStorage.getItem(devToolsStorageKeys.routeEvents.activeTab());
70
70
  if (storedTab && (storedTab === "routes" || storedTab === "events")) {
71
71
  setActiveTab(storedTab);
72
72
  }
@@ -83,7 +83,7 @@ export function RouteEventsModalWithTabs({
83
83
  if (!visible || hasLoadedMonitoringState.current) return;
84
84
  const loadMonitoringState = async () => {
85
85
  try {
86
- const storedMonitoring = await safeGetItem(devToolsStorageKeys.routeEvents.isMonitoring());
86
+ const storedMonitoring = await persistentStorage.getItem(devToolsStorageKeys.routeEvents.isMonitoring());
87
87
  if (storedMonitoring !== null) {
88
88
  const shouldMonitor = storedMonitoring === "true";
89
89
  setIsListening(shouldMonitor);
@@ -101,7 +101,7 @@ export function RouteEventsModalWithTabs({
101
101
  if (!hasLoadedTabState.current) return;
102
102
  const saveTabState = async () => {
103
103
  try {
104
- await safeSetItem(devToolsStorageKeys.routeEvents.activeTab(), activeTab);
104
+ await persistentStorage.setItem(devToolsStorageKeys.routeEvents.activeTab(), activeTab);
105
105
  } catch (error) {
106
106
  // Failed to save tab state
107
107
  }
@@ -114,7 +114,7 @@ export function RouteEventsModalWithTabs({
114
114
  if (!hasLoadedMonitoringState.current) return;
115
115
  const saveMonitoringState = async () => {
116
116
  try {
117
- await safeSetItem(devToolsStorageKeys.routeEvents.isMonitoring(), isListening.toString());
117
+ await persistentStorage.setItem(devToolsStorageKeys.routeEvents.isMonitoring(), isListening.toString());
118
118
  } catch (error) {
119
119
  // Failed to save monitoring state
120
120
  }
@@ -127,7 +127,7 @@ export function RouteEventsModalWithTabs({
127
127
  if (!visible || hasLoadedFilters.current) return;
128
128
  const loadFilters = async () => {
129
129
  try {
130
- const storedFilters = await safeGetItem(devToolsStorageKeys.routeEvents.eventFilters());
130
+ const storedFilters = await persistentStorage.getItem(devToolsStorageKeys.routeEvents.eventFilters());
131
131
  if (storedFilters) {
132
132
  const filters = JSON.parse(storedFilters);
133
133
  setIgnoredPatterns(new Set(filters));
@@ -146,7 +146,7 @@ export function RouteEventsModalWithTabs({
146
146
  const saveFilters = async () => {
147
147
  try {
148
148
  const filters = Array.from(ignoredPatterns);
149
- await safeSetItem(devToolsStorageKeys.routeEvents.eventFilters(), JSON.stringify(filters));
149
+ await persistentStorage.setItem(devToolsStorageKeys.routeEvents.eventFilters(), JSON.stringify(filters));
150
150
  } catch (error) {
151
151
  // Failed to save filters
152
152
  }
@@ -1,23 +1,54 @@
1
1
  "use strict";
2
2
 
3
- // Export route events modal (primary export - everything you need!)
4
- export { RouteEventsModalWithTabs } from "./components/RouteEventsModalWithTabs";
5
- // Export preset configuration (easiest way to add to FloatingDevTools!)
3
+ /**
4
+ * @buoy-gg/route-events
5
+ *
6
+ * Route tracking and navigation DevTools for React Native.
7
+ * Supports React Navigation and Expo Router.
8
+ *
9
+ * PUBLIC API - Only these exports are supported for external use.
10
+ */
11
+
12
+ // =============================================================================
13
+ // PRESET (Primary entry point for users)
14
+ // =============================================================================
6
15
  export { routeEventsToolPreset, createRouteEventsTool } from "./preset";
7
16
 
8
- // Export RouteTracker component - place inside your navigation tree for route tracking
17
+ // =============================================================================
18
+ // MAIN COMPONENT
19
+ // =============================================================================
20
+ export { RouteEventsModalWithTabs } from "./components/RouteEventsModalWithTabs";
21
+ // =============================================================================
22
+ // ROUTE TRACKER (Required - place inside your navigation tree)
23
+ // =============================================================================
9
24
  export { RouteTracker } from "./RouteTracker";
10
25
 
11
- // Export individual components for advanced usage
26
+ // =============================================================================
27
+ // COMPONENTS (For custom UI implementations)
28
+ // =============================================================================
12
29
  export { RoutesSitemap } from "./components/RoutesSitemap";
13
30
  export { NavigationStack } from "./components/NavigationStack";
14
- // Export advanced/optional utilities
15
- // Note: Most users won't need these - the modal handles everything automatically
16
- export { RouteObserver, routeObserver } from "./RouteObserver";
31
+ export { RouteEventItemCompact } from "./components/RouteEventItemCompact";
32
+ export { RouteEventExpandedContent } from "./components/RouteEventExpandedContent";
33
+ // =============================================================================
34
+ // HOOKS (For consuming route data)
35
+ // =============================================================================
17
36
  export { useRouteObserver } from "./useRouteObserver";
18
- // Export route parser utilities for advanced use cases
19
- export { RouteParser } from "./RouteParser";
20
- // Export route sitemap hooks for advanced use cases
21
37
  export { useRouteSitemap, useRoute, useParentRoutes } from "./useRouteSitemap";
22
- // Export navigation stack utilities for advanced use cases
23
- export { useNavigationStack } from "./useNavigationStack";
38
+ export { useNavigationStack } from "./useNavigationStack";
39
+
40
+ // =============================================================================
41
+ // TYPES
42
+ // =============================================================================
43
+
44
+ // =============================================================================
45
+ // UTILITIES (For advanced use cases)
46
+ // =============================================================================
47
+ export { RouteParser } from "./RouteParser";
48
+ export { RouteObserver } from "./RouteObserver";
49
+
50
+ // =============================================================================
51
+ // INTERNAL EXPORTS (For @buoy-gg/* packages only - not part of public API)
52
+ // =============================================================================
53
+ /** @internal - Singleton instance for cross-package communication */
54
+ export { routeObserver } from "./RouteObserver";
@@ -1 +1 @@
1
- {"version":3,"file":"RouteEventDetailContent.d.ts","sourceRoot":"","sources":["../../../src/components/RouteEventDetailContent.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAezD,UAAU,iBAAiB;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,gBAAgB,CAAC;IAC5B,MAAM,EAAE,gBAAgB,EAAE,CAAC;IAC3B,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,UAAU,4BAA4B;IACpC,YAAY,EAAE,iBAAiB,CAAC;IAChC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,kBAAkB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC;AAED,wBAAgB,uBAAuB,CAAC,EACtC,YAAY,EACZ,kBAAsB,EACtB,kBAA6B,EAC7B,qBAA6B,GAC9B,EAAE,4BAA4B,+BAwT9B;AAGD,wBAAgB,sBAAsB,CAAC,EACrC,YAAY,EACZ,kBAAsB,EACtB,kBAA6B,GAC9B,EAAE;IACD,YAAY,EAAE,iBAAiB,CAAC;IAChC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,kBAAkB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9C,sCA2EA"}
1
+ {"version":3,"file":"RouteEventDetailContent.d.ts","sourceRoot":"","sources":["../../../src/components/RouteEventDetailContent.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAczD,UAAU,iBAAiB;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,gBAAgB,CAAC;IAC5B,MAAM,EAAE,gBAAgB,EAAE,CAAC;IAC3B,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,UAAU,4BAA4B;IACpC,YAAY,EAAE,iBAAiB,CAAC;IAChC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,kBAAkB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC;AAED,wBAAgB,uBAAuB,CAAC,EACtC,YAAY,EACZ,kBAAsB,EACtB,kBAA6B,EAC7B,qBAA6B,GAC9B,EAAE,4BAA4B,+BAwT9B;AAGD,wBAAgB,sBAAsB,CAAC,EACrC,YAAY,EACZ,kBAAsB,EACtB,kBAA6B,GAC9B,EAAE;IACD,YAAY,EAAE,iBAAiB,CAAC;IAChC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,kBAAkB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9C,sCA2EA"}
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * RouteEventItemCompact - Compact list item for route events
3
3
  *
4
- * Uses CompactRow pattern matching network/storage components
4
+ * Uses CompactRow pattern matching network/storage/redux components
5
5
  */
6
6
  import type { RouteChangeEvent } from "../RouteObserver";
7
7
  export interface RouteEventItemCompactProps {
@@ -1 +1 @@
1
- {"version":3,"file":"RouteEventItemCompact.d.ts","sourceRoot":"","sources":["../../../src/components/RouteEventItemCompact.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAGzD,MAAM,WAAW,0BAA0B;IACzC,KAAK,EAAE,gBAAgB,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;IACpB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;CACzC;AAmFD,wBAAgB,qBAAqB,CAAC,EACpC,KAAK,EACL,WAAW,EACX,UAAU,EACV,OAAO,EACP,UAAU,GACX,EAAE,0BAA0B,+BAyD5B"}
1
+ {"version":3,"file":"RouteEventItemCompact.d.ts","sourceRoot":"","sources":["../../../src/components/RouteEventItemCompact.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAGzD,MAAM,WAAW,0BAA0B;IACzC,KAAK,EAAE,gBAAgB,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;IACpB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;CACzC;AA6GD,wBAAgB,qBAAqB,CAAC,EACpC,KAAK,EACL,WAAW,EACX,UAAU,EACV,OAAO,EACP,UAAU,GACX,EAAE,0BAA0B,+BA6D5B"}
@@ -1 +1 @@
1
- {"version":3,"file":"RouteEventsModalWithTabs.d.ts","sourceRoot":"","sources":["../../../src/components/RouteEventsModalWithTabs.tsx"],"names":[],"mappings":"AAoCA,OAAO,EACL,aAAa,IAAI,oBAAoB,EAEtC,MAAM,kBAAkB,CAAC;AAU1B,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;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,oBAAoB,CAAC;CAC7C;AAID,wBAAgB,wBAAwB,CAAC,EACvC,OAAO,EACP,OAAO,EACP,MAAM,EACN,UAAU,EACV,2BAAmC,EACnC,aAAoC,GACrC,EAAE,6BAA6B,sCA4hB/B"}
1
+ {"version":3,"file":"RouteEventsModalWithTabs.d.ts","sourceRoot":"","sources":["../../../src/components/RouteEventsModalWithTabs.tsx"],"names":[],"mappings":"AAmCA,OAAO,EACL,aAAa,IAAI,oBAAoB,EAEtC,MAAM,kBAAkB,CAAC;AAU1B,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;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,oBAAoB,CAAC;CAC7C;AAID,wBAAgB,wBAAwB,CAAC,EACvC,OAAO,EACP,OAAO,EACP,MAAM,EACN,UAAU,EACV,2BAAmC,EACnC,aAAoC,GACrC,EAAE,6BAA6B,sCA4hB/B"}
@@ -1,18 +1,32 @@
1
+ /**
2
+ * @buoy-gg/route-events
3
+ *
4
+ * Route tracking and navigation DevTools for React Native.
5
+ * Supports React Navigation and Expo Router.
6
+ *
7
+ * PUBLIC API - Only these exports are supported for external use.
8
+ */
9
+ export { routeEventsToolPreset, createRouteEventsTool } from "./preset";
1
10
  export { RouteEventsModalWithTabs } from "./components/RouteEventsModalWithTabs";
2
11
  export type { RouteEventsModalWithTabsProps } from "./components/RouteEventsModalWithTabs";
3
- export { routeEventsToolPreset, createRouteEventsTool } from "./preset";
4
12
  export { RouteTracker } from "./RouteTracker";
5
13
  export { RoutesSitemap } from "./components/RoutesSitemap";
6
14
  export type { RoutesSitemapProps } from "./components/RoutesSitemap";
7
15
  export { NavigationStack } from "./components/NavigationStack";
8
16
  export type { NavigationStackProps } from "./components/NavigationStack";
9
- export { RouteObserver, routeObserver } from "./RouteObserver";
17
+ export { RouteEventItemCompact } from "./components/RouteEventItemCompact";
18
+ export type { RouteEventItemCompactProps } from "./components/RouteEventItemCompact";
19
+ export { RouteEventExpandedContent } from "./components/RouteEventExpandedContent";
20
+ export type { RouteEventExpandedContentProps } from "./components/RouteEventExpandedContent";
10
21
  export { useRouteObserver } from "./useRouteObserver";
11
- export type { RouteChangeEvent } from "./RouteObserver";
12
- export { RouteParser } from "./RouteParser";
13
- export type { RouteInfo, RouteType, RouteGroup, RouteStats, } from "./RouteParser";
14
22
  export { useRouteSitemap, useRoute, useParentRoutes } from "./useRouteSitemap";
15
23
  export type { UseRouteSitemapOptions, UseRouteSitemapResult, } from "./useRouteSitemap";
16
24
  export { useNavigationStack } from "./useNavigationStack";
17
25
  export type { UseNavigationStackResult, StackDisplayItem, } from "./useNavigationStack";
26
+ export type { RouteChangeEvent } from "./RouteObserver";
27
+ export type { RouteInfo, RouteType, RouteGroup, RouteStats, } from "./RouteParser";
28
+ export { RouteParser } from "./RouteParser";
29
+ export { RouteObserver } from "./RouteObserver";
30
+ /** @internal - Singleton instance for cross-package communication */
31
+ export { routeObserver } from "./RouteObserver";
18
32
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,wBAAwB,EAAE,MAAM,uCAAuC,CAAC;AACjF,YAAY,EAAE,6BAA6B,EAAE,MAAM,uCAAuC,CAAC;AAG3F,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAGxE,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAG9C,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;AAIzE,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,YAAY,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAGxD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,YAAY,EACV,SAAS,EACT,SAAS,EACT,UAAU,EACV,UAAU,GACX,MAAM,eAAe,CAAC;AAGvB,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAC/E,YAAY,EACV,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,YAAY,EACV,wBAAwB,EACxB,gBAAgB,GACjB,MAAM,sBAAsB,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,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,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"}
package/package.json CHANGED
@@ -1,19 +1,33 @@
1
1
  {
2
2
  "name": "@buoy-gg/route-events",
3
- "version": "1.7.8",
3
+ "version": "2.1.2",
4
4
  "description": "route-events package",
5
5
  "main": "lib/commonjs/index.js",
6
6
  "module": "lib/module/index.js",
7
7
  "types": "lib/typescript/index.d.ts",
8
8
  "react-native": "lib/module/index.js",
9
9
  "source": "src/index.tsx",
10
+ "exports": {
11
+ ".": {
12
+ "react-native": "./lib/module/index.js",
13
+ "import": {
14
+ "default": "./lib/module/index.js",
15
+ "types": "./lib/typescript/index.d.ts"
16
+ },
17
+ "require": {
18
+ "default": "./lib/commonjs/index.js",
19
+ "types": "./lib/typescript/index.d.ts"
20
+ }
21
+ },
22
+ "./package.json": "./package.json"
23
+ },
10
24
  "files": [
11
25
  "lib"
12
26
  ],
13
27
  "sideEffects": false,
14
28
  "dependencies": {
15
- "@buoy-gg/floating-tools-core": "1.7.8",
16
- "@buoy-gg/shared-ui": "1.7.8"
29
+ "@buoy-gg/floating-tools-core": "2.1.2",
30
+ "@buoy-gg/shared-ui": "2.1.2"
17
31
  },
18
32
  "peerDependencies": {
19
33
  "@buoy-gg/license": "*",
@@ -35,7 +49,7 @@
35
49
  "@types/react-native": "^0.73.0",
36
50
  "expo-router": "~5.0.7",
37
51
  "typescript": "~5.8.3",
38
- "@buoy-gg/license": "1.7.8"
52
+ "@buoy-gg/license": "2.1.2"
39
53
  },
40
54
  "react-native-builder-bob": {
41
55
  "source": "src",