@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.
- package/lib/commonjs/components/RouteEventDetailContent.js +2 -2
- package/lib/commonjs/components/RouteEventItemCompact.js +58 -29
- package/lib/commonjs/components/RouteEventsModalWithTabs.js +6 -6
- package/lib/commonjs/index.js +18 -4
- package/lib/module/components/RouteEventDetailContent.js +3 -3
- package/lib/module/components/RouteEventItemCompact.js +58 -29
- package/lib/module/components/RouteEventsModalWithTabs.js +7 -7
- package/lib/module/index.js +44 -13
- package/lib/typescript/components/RouteEventDetailContent.d.ts.map +1 -1
- package/lib/typescript/components/RouteEventItemCompact.d.ts +1 -1
- package/lib/typescript/components/RouteEventItemCompact.d.ts.map +1 -1
- package/lib/typescript/components/RouteEventsModalWithTabs.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +19 -5
- package/lib/typescript/index.d.ts.map +1 -1
- package/package.json +18 -4
|
@@ -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
|
|
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
|
|
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.
|
|
65
|
-
//
|
|
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
|
-
//
|
|
84
|
-
function
|
|
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 (
|
|
87
|
-
|
|
109
|
+
if (hasParams) {
|
|
110
|
+
const paramCount = Object.keys(event.params).length;
|
|
111
|
+
return `${paramCount} PARAM${paramCount !== 1 ? "S" : ""}`;
|
|
88
112
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
return
|
|
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
|
|
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.
|
|
125
|
-
|
|
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
|
-
}, [
|
|
162
|
+
}, [onNavigate, event.pathname, badgeText, statusColor]);
|
|
139
163
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.CompactRow, {
|
|
140
164
|
statusDotColor: statusColor,
|
|
141
165
|
statusLabel: statusLabel,
|
|
142
|
-
|
|
143
|
-
|
|
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
|
-
|
|
159
|
-
fontSize:
|
|
160
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
152
|
+
await _sharedUi.persistentStorage.setItem(_sharedUi.devToolsStorageKeys.routeEvents.eventFilters(), JSON.stringify(filters));
|
|
153
153
|
} catch (error) {
|
|
154
154
|
// Failed to save filters
|
|
155
155
|
}
|
package/lib/commonjs/index.js
CHANGED
|
@@ -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
|
|
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,
|
|
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
|
|
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
|
|
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.
|
|
61
|
-
//
|
|
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
|
-
//
|
|
80
|
-
function
|
|
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 (
|
|
83
|
-
|
|
105
|
+
if (hasParams) {
|
|
106
|
+
const paramCount = Object.keys(event.params).length;
|
|
107
|
+
return `${paramCount} PARAM${paramCount !== 1 ? "S" : ""}`;
|
|
84
108
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
return
|
|
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
|
|
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.
|
|
121
|
-
|
|
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
|
-
}, [
|
|
158
|
+
}, [onNavigate, event.pathname, badgeText, statusColor]);
|
|
135
159
|
return /*#__PURE__*/_jsx(CompactRow, {
|
|
136
160
|
statusDotColor: statusColor,
|
|
137
161
|
statusLabel: statusLabel,
|
|
138
|
-
|
|
139
|
-
|
|
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
|
-
|
|
155
|
-
fontSize:
|
|
156
|
-
|
|
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,
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
149
|
+
await persistentStorage.setItem(devToolsStorageKeys.routeEvents.eventFilters(), JSON.stringify(filters));
|
|
150
150
|
} catch (error) {
|
|
151
151
|
// Failed to save filters
|
|
152
152
|
}
|
package/lib/module/index.js
CHANGED
|
@@ -1,23 +1,54 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
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
|
-
//
|
|
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
|
-
//
|
|
26
|
+
// =============================================================================
|
|
27
|
+
// COMPONENTS (For custom UI implementations)
|
|
28
|
+
// =============================================================================
|
|
12
29
|
export { RoutesSitemap } from "./components/RoutesSitemap";
|
|
13
30
|
export { NavigationStack } from "./components/NavigationStack";
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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
|
-
|
|
23
|
-
|
|
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;
|
|
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;
|
|
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":"
|
|
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 {
|
|
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":"
|
|
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.
|
|
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.
|
|
16
|
-
"@buoy-gg/shared-ui": "1.
|
|
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.
|
|
52
|
+
"@buoy-gg/license": "2.1.2"
|
|
39
53
|
},
|
|
40
54
|
"react-native-builder-bob": {
|
|
41
55
|
"source": "src",
|