@buoy-gg/zustand 7.0.31 → 7.0.33
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/zustand/components/ZustandModal.js +67 -59
- package/lib/commonjs/zustand/components/ZustandStoreBrowser.js +29 -54
- package/lib/module/zustand/components/ZustandModal.js +68 -60
- package/lib/module/zustand/components/ZustandStoreBrowser.js +31 -56
- package/lib/typescript/zustand/components/ZustandModal.d.ts.map +1 -1
- package/lib/typescript/zustand/components/ZustandStoreBrowser.d.ts.map +1 -1
- package/package.json +3 -3
|
@@ -35,24 +35,34 @@ var _jsxRuntime = require("react/jsx-runtime");
|
|
|
35
35
|
* production behaviour exactly as it was.
|
|
36
36
|
*/
|
|
37
37
|
const CLIP_OFFSCREEN_CELLS = !(typeof process !== "undefined" && process.env?.EXPO_PUBLIC_E2E);
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* The change log's "nothing here". Everything but the nouns is the shared
|
|
41
|
+
* precedence — see `ToolEmptyState` in shared-ui for why it lives there.
|
|
42
|
+
*/
|
|
38
43
|
function EventsEmptyState({
|
|
39
|
-
isEnabled
|
|
44
|
+
isEnabled,
|
|
45
|
+
searchText,
|
|
46
|
+
totalChanges
|
|
40
47
|
}) {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
48
|
+
const content = (0, _sharedUi.resolveListEmptyState)({
|
|
49
|
+
subject: "changes",
|
|
50
|
+
search: searchText,
|
|
51
|
+
total: totalChanges,
|
|
52
|
+
capturing: isEnabled,
|
|
53
|
+
waiting: {
|
|
54
|
+
otto: "waiting",
|
|
55
|
+
title: "No state changes",
|
|
56
|
+
message: "State changes will appear here as stores update."
|
|
57
|
+
},
|
|
58
|
+
paused: {
|
|
59
|
+
title: "No state changes",
|
|
60
|
+
message: "Enable capture to start recording state changes"
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ToolEmptyState, {
|
|
64
|
+
...content,
|
|
65
|
+
testID: `${_testIDs.ZUSTAND_TEST_ID}-empty`
|
|
56
66
|
});
|
|
57
67
|
}
|
|
58
68
|
function ZustandModal({
|
|
@@ -82,6 +92,7 @@ function ZustandModal({
|
|
|
82
92
|
const [showFilters, setShowFilters] = (0, _react.useState)(false);
|
|
83
93
|
const [ignoredPatterns, setIgnoredPatterns] = (0, _react.useState)(new Set());
|
|
84
94
|
const {
|
|
95
|
+
stateChanges,
|
|
85
96
|
filteredChanges,
|
|
86
97
|
filter,
|
|
87
98
|
setFilter,
|
|
@@ -104,6 +115,16 @@ function ZustandModal({
|
|
|
104
115
|
return stores.filter(s => !Array.from(ignoredPatterns).some(p => s.name.toLowerCase().includes(p.toLowerCase())));
|
|
105
116
|
}, [stores, ignoredPatterns]);
|
|
106
117
|
|
|
118
|
+
/**
|
|
119
|
+
* How many changes this store has captured, before the search — the
|
|
120
|
+
* denominator the scoped empty state needs so "clear the search" is only
|
|
121
|
+
* offered when clearing it would actually show something.
|
|
122
|
+
*/
|
|
123
|
+
const scopedTotalForStore = (0, _react.useMemo)(() => {
|
|
124
|
+
if (!selectedHistoryStore) return 0;
|
|
125
|
+
return stateChanges.filter(c => c.storeName === selectedHistoryStore).length;
|
|
126
|
+
}, [stateChanges, selectedHistoryStore]);
|
|
127
|
+
|
|
107
128
|
// Scope to a store BEFORE the tier cap, not after.
|
|
108
129
|
//
|
|
109
130
|
// The other way round, the cap was applied to the whole log and a store's
|
|
@@ -511,19 +532,24 @@ function ZustandModal({
|
|
|
511
532
|
maxToRenderPerBatch: 8,
|
|
512
533
|
windowSize: 5,
|
|
513
534
|
updateCellsBatchingPeriod: 50
|
|
514
|
-
}) : /*#__PURE__*/(0, _jsxRuntime.
|
|
515
|
-
style: styles.emptyState,
|
|
535
|
+
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ToolEmptyState, {
|
|
516
536
|
testID: `${_testIDs.ZUSTAND_TEST_ID}-history-empty`,
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
537
|
+
...(0, _sharedUi.resolveListEmptyState)({
|
|
538
|
+
subject: "changes",
|
|
539
|
+
search: searchText,
|
|
540
|
+
// Scoped to one store, so the count is this store's, not the log's.
|
|
541
|
+
total: searchText.trim() ? scopedTotalForStore : 0,
|
|
542
|
+
capturing: isEnabled,
|
|
543
|
+
waiting: {
|
|
544
|
+
otto: "waiting",
|
|
545
|
+
title: "No history yet",
|
|
546
|
+
message: `State changes for ${selectedHistoryStore} will appear here.`
|
|
547
|
+
},
|
|
548
|
+
paused: {
|
|
549
|
+
title: "No history yet",
|
|
550
|
+
message: `Capture is off, so nothing is being recorded for ${selectedHistoryStore}.`
|
|
551
|
+
}
|
|
552
|
+
})
|
|
527
553
|
});
|
|
528
554
|
}
|
|
529
555
|
|
|
@@ -539,19 +565,15 @@ function ZustandModal({
|
|
|
539
565
|
/*#__PURE__*/
|
|
540
566
|
// The store fell out of the registry mid-look (a remote mirror
|
|
541
567
|
// rebuilding, a dev reload). Say so rather than rendering nothing.
|
|
542
|
-
(0, _jsxRuntime.
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
|
|
552
|
-
style: styles.emptyText,
|
|
553
|
-
children: [selectedStoreName, " is not in the registry any more."]
|
|
554
|
-
})]
|
|
568
|
+
(0, _jsxRuntime.jsx)(_sharedUi.ToolEmptyState, {
|
|
569
|
+
testID: `${_testIDs.ZUSTAND_TEST_ID}-store-detail-gone`
|
|
570
|
+
// ghost = "stale or detached: an unmounted component, an old
|
|
571
|
+
// snapshot" — exactly what the store you are looking at has become.
|
|
572
|
+
// No other tool has this cause, so it skips the resolver.
|
|
573
|
+
,
|
|
574
|
+
otto: "ghost",
|
|
575
|
+
title: "Store no longer registered",
|
|
576
|
+
message: `${selectedStoreName} is not in the registry any more.`
|
|
555
577
|
});
|
|
556
578
|
}
|
|
557
579
|
|
|
@@ -611,7 +633,9 @@ function ZustandModal({
|
|
|
611
633
|
windowSize: 5,
|
|
612
634
|
updateCellsBatchingPeriod: 50
|
|
613
635
|
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(EventsEmptyState, {
|
|
614
|
-
isEnabled: isEnabled
|
|
636
|
+
isEnabled: isEnabled,
|
|
637
|
+
searchText: searchText,
|
|
638
|
+
totalChanges: stats.totalChanges
|
|
615
639
|
})]
|
|
616
640
|
});
|
|
617
641
|
};
|
|
@@ -656,6 +680,7 @@ function ZustandModal({
|
|
|
656
680
|
style: styles.inlineRoot,
|
|
657
681
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
658
682
|
style: styles.inlineHeader,
|
|
683
|
+
..._sharedUi.windowDragProps,
|
|
659
684
|
children: renderHeaderContent()
|
|
660
685
|
}), body, footerNode]
|
|
661
686
|
}), upgradeModal]
|
|
@@ -778,23 +803,6 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
778
803
|
paddingTop: 8,
|
|
779
804
|
paddingBottom: 20
|
|
780
805
|
},
|
|
781
|
-
emptyState: {
|
|
782
|
-
alignItems: "center",
|
|
783
|
-
paddingVertical: 40
|
|
784
|
-
},
|
|
785
|
-
emptyTitle: {
|
|
786
|
-
color: _sharedUi.night.color.text,
|
|
787
|
-
fontSize: 14,
|
|
788
|
-
fontWeight: "600",
|
|
789
|
-
marginTop: 12,
|
|
790
|
-
marginBottom: 6
|
|
791
|
-
},
|
|
792
|
-
emptyText: {
|
|
793
|
-
color: _sharedUi.night.color.textTertiary,
|
|
794
|
-
fontSize: 12,
|
|
795
|
-
textAlign: "center",
|
|
796
|
-
lineHeight: 18
|
|
797
|
-
},
|
|
798
806
|
lockedBanner: {
|
|
799
807
|
flexDirection: "row",
|
|
800
808
|
alignItems: "center",
|
|
@@ -44,36 +44,26 @@ function getKeysPreview(store) {
|
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
function LoadingBrowserState() {
|
|
47
|
-
return /*#__PURE__*/(0, _jsxRuntime.
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
57
|
-
style: styles.emptyText,
|
|
58
|
-
children: "Waiting for the device to send its registered stores."
|
|
59
|
-
})]
|
|
47
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ToolEmptyState, {
|
|
48
|
+
testID: `${_testIDs.ZUSTAND_TEST_ID}-stores-loading`
|
|
49
|
+
// Replaces the spinner rather than joining it: two animated things
|
|
50
|
+
// stacked is clutter, and `loading` IS the indeterminate spinner in
|
|
51
|
+
// mascot form.
|
|
52
|
+
,
|
|
53
|
+
otto: "loading",
|
|
54
|
+
title: "Loading stores\u2026",
|
|
55
|
+
message: "Waiting for the device to send its registered stores."
|
|
60
56
|
});
|
|
61
57
|
}
|
|
62
58
|
function EmptyBrowserState() {
|
|
63
|
-
return /*#__PURE__*/(0, _jsxRuntime.
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
testID: `${_testIDs.ZUSTAND_TEST_ID}-stores-empty-title`,
|
|
72
|
-
children: "No stores registered"
|
|
73
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
74
|
-
style: styles.emptyText,
|
|
75
|
-
children: "Use watchStores() to register your Zustand stores.\nThey will appear here with their current state."
|
|
76
|
-
})]
|
|
59
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ToolEmptyState, {
|
|
60
|
+
testID: `${_testIDs.ZUSTAND_TEST_ID}-stores-empty`
|
|
61
|
+
// scanning = "scanning for targets… and finding none". The registry is
|
|
62
|
+
// discovered, not configured, so an empty one is a scan result.
|
|
63
|
+
,
|
|
64
|
+
otto: "scanning",
|
|
65
|
+
title: "No stores registered",
|
|
66
|
+
message: "Use watchStores() to register your Zustand stores.\nThey will appear here with their current state."
|
|
77
67
|
});
|
|
78
68
|
}
|
|
79
69
|
function ZustandStoreBrowser({
|
|
@@ -92,17 +82,19 @@ function ZustandStoreBrowser({
|
|
|
92
82
|
return isLoading ? /*#__PURE__*/(0, _jsxRuntime.jsx)(LoadingBrowserState, {}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(EmptyBrowserState, {});
|
|
93
83
|
}
|
|
94
84
|
if (filteredStores.length === 0 && searchQuery) {
|
|
95
|
-
return /*#__PURE__*/(0, _jsxRuntime.
|
|
96
|
-
style: styles.emptyState,
|
|
85
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ToolEmptyState, {
|
|
97
86
|
testID: `${_testIDs.ZUSTAND_TEST_ID}-stores-no-match`,
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
87
|
+
...(0, _sharedUi.resolveListEmptyState)({
|
|
88
|
+
subject: "stores",
|
|
89
|
+
verb: "registered",
|
|
90
|
+
search: searchQuery,
|
|
91
|
+
total: stores.length,
|
|
92
|
+
waiting: {
|
|
93
|
+
otto: "scanning",
|
|
94
|
+
title: "No stores registered",
|
|
95
|
+
message: "Use watchStores() to register your Zustand stores."
|
|
96
|
+
}
|
|
97
|
+
})
|
|
106
98
|
});
|
|
107
99
|
}
|
|
108
100
|
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.ScrollView, {
|
|
@@ -208,22 +200,5 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
208
200
|
fontWeight: "700",
|
|
209
201
|
color: _sharedUi.night.color.accent,
|
|
210
202
|
fontFamily: "monospace"
|
|
211
|
-
},
|
|
212
|
-
emptyState: {
|
|
213
|
-
alignItems: "center",
|
|
214
|
-
paddingVertical: 40
|
|
215
|
-
},
|
|
216
|
-
emptyTitle: {
|
|
217
|
-
color: _sharedUi.night.color.text,
|
|
218
|
-
fontSize: 14,
|
|
219
|
-
fontWeight: "600",
|
|
220
|
-
marginTop: 12,
|
|
221
|
-
marginBottom: 6
|
|
222
|
-
},
|
|
223
|
-
emptyText: {
|
|
224
|
-
color: _sharedUi.night.color.textTertiary,
|
|
225
|
-
fontSize: 12,
|
|
226
|
-
textAlign: "center",
|
|
227
|
-
lineHeight: 18
|
|
228
203
|
}
|
|
229
204
|
});
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
import { useState, useMemo, useRef, useCallback, useEffect } from "react";
|
|
12
12
|
import { View, Text, StyleSheet, FlatList, TextInput, TouchableOpacity } from "react-native";
|
|
13
|
-
import { JsModal, ModalHeader, TabSelector, macOSColors, night, Search, Filter, Power, X, Lock,
|
|
13
|
+
import { JsModal, ModalHeader, TabSelector, macOSColors, night, ToolEmptyState, resolveListEmptyState, Search, Filter, Power, X, Lock, devToolsStorageKeys, ProUpgradeModal, PowerToggleButton, ToolbarCopyButton, ToolbarClearButton, truncatePayload, TickProvider, useLimit, windowDragProps } from "@buoy-gg/shared-ui";
|
|
14
14
|
import { useIsPro } from "@buoy-gg/license";
|
|
15
15
|
import { useZustandStateChanges } from "../hooks/useZustandStateChanges";
|
|
16
16
|
import { ZustandStateChangeItem } from "./ZustandStateChangeItem";
|
|
@@ -30,24 +30,34 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
30
30
|
* production behaviour exactly as it was.
|
|
31
31
|
*/
|
|
32
32
|
const CLIP_OFFSCREEN_CELLS = !(typeof process !== "undefined" && process.env?.EXPO_PUBLIC_E2E);
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* The change log's "nothing here". Everything but the nouns is the shared
|
|
36
|
+
* precedence — see `ToolEmptyState` in shared-ui for why it lives there.
|
|
37
|
+
*/
|
|
33
38
|
function EventsEmptyState({
|
|
34
|
-
isEnabled
|
|
39
|
+
isEnabled,
|
|
40
|
+
searchText,
|
|
41
|
+
totalChanges
|
|
35
42
|
}) {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
43
|
+
const content = resolveListEmptyState({
|
|
44
|
+
subject: "changes",
|
|
45
|
+
search: searchText,
|
|
46
|
+
total: totalChanges,
|
|
47
|
+
capturing: isEnabled,
|
|
48
|
+
waiting: {
|
|
49
|
+
otto: "waiting",
|
|
50
|
+
title: "No state changes",
|
|
51
|
+
message: "State changes will appear here as stores update."
|
|
52
|
+
},
|
|
53
|
+
paused: {
|
|
54
|
+
title: "No state changes",
|
|
55
|
+
message: "Enable capture to start recording state changes"
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
return /*#__PURE__*/_jsx(ToolEmptyState, {
|
|
59
|
+
...content,
|
|
60
|
+
testID: `${ZUSTAND_TEST_ID}-empty`
|
|
51
61
|
});
|
|
52
62
|
}
|
|
53
63
|
export function ZustandModal({
|
|
@@ -77,6 +87,7 @@ export function ZustandModal({
|
|
|
77
87
|
const [showFilters, setShowFilters] = useState(false);
|
|
78
88
|
const [ignoredPatterns, setIgnoredPatterns] = useState(new Set());
|
|
79
89
|
const {
|
|
90
|
+
stateChanges,
|
|
80
91
|
filteredChanges,
|
|
81
92
|
filter,
|
|
82
93
|
setFilter,
|
|
@@ -99,6 +110,16 @@ export function ZustandModal({
|
|
|
99
110
|
return stores.filter(s => !Array.from(ignoredPatterns).some(p => s.name.toLowerCase().includes(p.toLowerCase())));
|
|
100
111
|
}, [stores, ignoredPatterns]);
|
|
101
112
|
|
|
113
|
+
/**
|
|
114
|
+
* How many changes this store has captured, before the search — the
|
|
115
|
+
* denominator the scoped empty state needs so "clear the search" is only
|
|
116
|
+
* offered when clearing it would actually show something.
|
|
117
|
+
*/
|
|
118
|
+
const scopedTotalForStore = useMemo(() => {
|
|
119
|
+
if (!selectedHistoryStore) return 0;
|
|
120
|
+
return stateChanges.filter(c => c.storeName === selectedHistoryStore).length;
|
|
121
|
+
}, [stateChanges, selectedHistoryStore]);
|
|
122
|
+
|
|
102
123
|
// Scope to a store BEFORE the tier cap, not after.
|
|
103
124
|
//
|
|
104
125
|
// The other way round, the cap was applied to the whole log and a store's
|
|
@@ -506,19 +527,24 @@ export function ZustandModal({
|
|
|
506
527
|
maxToRenderPerBatch: 8,
|
|
507
528
|
windowSize: 5,
|
|
508
529
|
updateCellsBatchingPeriod: 50
|
|
509
|
-
}) : /*#__PURE__*/
|
|
510
|
-
style: styles.emptyState,
|
|
530
|
+
}) : /*#__PURE__*/_jsx(ToolEmptyState, {
|
|
511
531
|
testID: `${ZUSTAND_TEST_ID}-history-empty`,
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
532
|
+
...resolveListEmptyState({
|
|
533
|
+
subject: "changes",
|
|
534
|
+
search: searchText,
|
|
535
|
+
// Scoped to one store, so the count is this store's, not the log's.
|
|
536
|
+
total: searchText.trim() ? scopedTotalForStore : 0,
|
|
537
|
+
capturing: isEnabled,
|
|
538
|
+
waiting: {
|
|
539
|
+
otto: "waiting",
|
|
540
|
+
title: "No history yet",
|
|
541
|
+
message: `State changes for ${selectedHistoryStore} will appear here.`
|
|
542
|
+
},
|
|
543
|
+
paused: {
|
|
544
|
+
title: "No history yet",
|
|
545
|
+
message: `Capture is off, so nothing is being recorded for ${selectedHistoryStore}.`
|
|
546
|
+
}
|
|
547
|
+
})
|
|
522
548
|
});
|
|
523
549
|
}
|
|
524
550
|
|
|
@@ -534,19 +560,15 @@ export function ZustandModal({
|
|
|
534
560
|
/*#__PURE__*/
|
|
535
561
|
// The store fell out of the registry mid-look (a remote mirror
|
|
536
562
|
// rebuilding, a dev reload). Say so rather than rendering nothing.
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
}), /*#__PURE__*/_jsxs(Text, {
|
|
547
|
-
style: styles.emptyText,
|
|
548
|
-
children: [selectedStoreName, " is not in the registry any more."]
|
|
549
|
-
})]
|
|
563
|
+
_jsx(ToolEmptyState, {
|
|
564
|
+
testID: `${ZUSTAND_TEST_ID}-store-detail-gone`
|
|
565
|
+
// ghost = "stale or detached: an unmounted component, an old
|
|
566
|
+
// snapshot" — exactly what the store you are looking at has become.
|
|
567
|
+
// No other tool has this cause, so it skips the resolver.
|
|
568
|
+
,
|
|
569
|
+
otto: "ghost",
|
|
570
|
+
title: "Store no longer registered",
|
|
571
|
+
message: `${selectedStoreName} is not in the registry any more.`
|
|
550
572
|
});
|
|
551
573
|
}
|
|
552
574
|
|
|
@@ -606,7 +628,9 @@ export function ZustandModal({
|
|
|
606
628
|
windowSize: 5,
|
|
607
629
|
updateCellsBatchingPeriod: 50
|
|
608
630
|
}) : /*#__PURE__*/_jsx(EventsEmptyState, {
|
|
609
|
-
isEnabled: isEnabled
|
|
631
|
+
isEnabled: isEnabled,
|
|
632
|
+
searchText: searchText,
|
|
633
|
+
totalChanges: stats.totalChanges
|
|
610
634
|
})]
|
|
611
635
|
});
|
|
612
636
|
};
|
|
@@ -651,6 +675,7 @@ export function ZustandModal({
|
|
|
651
675
|
style: styles.inlineRoot,
|
|
652
676
|
children: [/*#__PURE__*/_jsx(View, {
|
|
653
677
|
style: styles.inlineHeader,
|
|
678
|
+
...windowDragProps,
|
|
654
679
|
children: renderHeaderContent()
|
|
655
680
|
}), body, footerNode]
|
|
656
681
|
}), upgradeModal]
|
|
@@ -773,23 +798,6 @@ const styles = StyleSheet.create({
|
|
|
773
798
|
paddingTop: 8,
|
|
774
799
|
paddingBottom: 20
|
|
775
800
|
},
|
|
776
|
-
emptyState: {
|
|
777
|
-
alignItems: "center",
|
|
778
|
-
paddingVertical: 40
|
|
779
|
-
},
|
|
780
|
-
emptyTitle: {
|
|
781
|
-
color: night.color.text,
|
|
782
|
-
fontSize: 14,
|
|
783
|
-
fontWeight: "600",
|
|
784
|
-
marginTop: 12,
|
|
785
|
-
marginBottom: 6
|
|
786
|
-
},
|
|
787
|
-
emptyText: {
|
|
788
|
-
color: night.color.textTertiary,
|
|
789
|
-
fontSize: 12,
|
|
790
|
-
textAlign: "center",
|
|
791
|
-
lineHeight: 18
|
|
792
|
-
},
|
|
793
801
|
lockedBanner: {
|
|
794
802
|
flexDirection: "row",
|
|
795
803
|
alignItems: "center",
|
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
import { useMemo } from "react";
|
|
13
|
-
import { View, Text, StyleSheet, ScrollView
|
|
14
|
-
import { CompactRow, night,
|
|
13
|
+
import { View, Text, StyleSheet, ScrollView } from "react-native";
|
|
14
|
+
import { CompactRow, night, ToolEmptyState, resolveListEmptyState } from "@buoy-gg/shared-ui";
|
|
15
15
|
import { zustandStateStore } from "../utils/zustandStateStore";
|
|
16
16
|
import { ZUSTAND_TEST_ID, storeRowTestID } from "../utils/testIDs";
|
|
17
17
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
@@ -40,36 +40,26 @@ function getKeysPreview(store) {
|
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
42
|
function LoadingBrowserState() {
|
|
43
|
-
return /*#__PURE__*/
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}), /*#__PURE__*/_jsx(Text, {
|
|
53
|
-
style: styles.emptyText,
|
|
54
|
-
children: "Waiting for the device to send its registered stores."
|
|
55
|
-
})]
|
|
43
|
+
return /*#__PURE__*/_jsx(ToolEmptyState, {
|
|
44
|
+
testID: `${ZUSTAND_TEST_ID}-stores-loading`
|
|
45
|
+
// Replaces the spinner rather than joining it: two animated things
|
|
46
|
+
// stacked is clutter, and `loading` IS the indeterminate spinner in
|
|
47
|
+
// mascot form.
|
|
48
|
+
,
|
|
49
|
+
otto: "loading",
|
|
50
|
+
title: "Loading stores\u2026",
|
|
51
|
+
message: "Waiting for the device to send its registered stores."
|
|
56
52
|
});
|
|
57
53
|
}
|
|
58
54
|
function EmptyBrowserState() {
|
|
59
|
-
return /*#__PURE__*/
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
testID: `${ZUSTAND_TEST_ID}-stores-empty-title`,
|
|
68
|
-
children: "No stores registered"
|
|
69
|
-
}), /*#__PURE__*/_jsx(Text, {
|
|
70
|
-
style: styles.emptyText,
|
|
71
|
-
children: "Use watchStores() to register your Zustand stores.\nThey will appear here with their current state."
|
|
72
|
-
})]
|
|
55
|
+
return /*#__PURE__*/_jsx(ToolEmptyState, {
|
|
56
|
+
testID: `${ZUSTAND_TEST_ID}-stores-empty`
|
|
57
|
+
// scanning = "scanning for targets… and finding none". The registry is
|
|
58
|
+
// discovered, not configured, so an empty one is a scan result.
|
|
59
|
+
,
|
|
60
|
+
otto: "scanning",
|
|
61
|
+
title: "No stores registered",
|
|
62
|
+
message: "Use watchStores() to register your Zustand stores.\nThey will appear here with their current state."
|
|
73
63
|
});
|
|
74
64
|
}
|
|
75
65
|
export function ZustandStoreBrowser({
|
|
@@ -88,17 +78,19 @@ export function ZustandStoreBrowser({
|
|
|
88
78
|
return isLoading ? /*#__PURE__*/_jsx(LoadingBrowserState, {}) : /*#__PURE__*/_jsx(EmptyBrowserState, {});
|
|
89
79
|
}
|
|
90
80
|
if (filteredStores.length === 0 && searchQuery) {
|
|
91
|
-
return /*#__PURE__*/
|
|
92
|
-
style: styles.emptyState,
|
|
81
|
+
return /*#__PURE__*/_jsx(ToolEmptyState, {
|
|
93
82
|
testID: `${ZUSTAND_TEST_ID}-stores-no-match`,
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
83
|
+
...resolveListEmptyState({
|
|
84
|
+
subject: "stores",
|
|
85
|
+
verb: "registered",
|
|
86
|
+
search: searchQuery,
|
|
87
|
+
total: stores.length,
|
|
88
|
+
waiting: {
|
|
89
|
+
otto: "scanning",
|
|
90
|
+
title: "No stores registered",
|
|
91
|
+
message: "Use watchStores() to register your Zustand stores."
|
|
92
|
+
}
|
|
93
|
+
})
|
|
102
94
|
});
|
|
103
95
|
}
|
|
104
96
|
return /*#__PURE__*/_jsxs(ScrollView, {
|
|
@@ -204,22 +196,5 @@ const styles = StyleSheet.create({
|
|
|
204
196
|
fontWeight: "700",
|
|
205
197
|
color: night.color.accent,
|
|
206
198
|
fontFamily: "monospace"
|
|
207
|
-
},
|
|
208
|
-
emptyState: {
|
|
209
|
-
alignItems: "center",
|
|
210
|
-
paddingVertical: 40
|
|
211
|
-
},
|
|
212
|
-
emptyTitle: {
|
|
213
|
-
color: night.color.text,
|
|
214
|
-
fontSize: 14,
|
|
215
|
-
fontWeight: "600",
|
|
216
|
-
marginTop: 12,
|
|
217
|
-
marginBottom: 6
|
|
218
|
-
},
|
|
219
|
-
emptyText: {
|
|
220
|
-
color: night.color.textTertiary,
|
|
221
|
-
fontSize: 12,
|
|
222
|
-
textAlign: "center",
|
|
223
|
-
lineHeight: 18
|
|
224
199
|
}
|
|
225
200
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ZustandModal.d.ts","sourceRoot":"","sources":["../../../../src/zustand/components/ZustandModal.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
1
|
+
{"version":3,"file":"ZustandModal.d.ts","sourceRoot":"","sources":["../../../../src/zustand/components/ZustandModal.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAiDH,OAAO,KAAK,EAAE,iBAAiB,EAAsB,MAAM,UAAU,CAAC;AAkDtE,wBAAgB,YAAY,CAAC,EAC3B,OAAO,EACP,OAAO,EACP,MAAM,EACN,UAAU,EACV,2BAAmC,EACnC,MAAc,EACd,aAAqB,EACrB,UAAqB,EACrB,uBAAuB,EACvB,iBAAiB,EACjB,cAAc,EACd,aAAa,GACd,EAAE,iBAAiB,sCAiwBnB;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,KAAK,GAAE,IAAI,CAAC,iBAAiB,EAAE,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAM,+BAGtE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ZustandStoreBrowser.d.ts","sourceRoot":"","sources":["../../../../src/zustand/components/ZustandStoreBrowser.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;
|
|
1
|
+
{"version":3,"file":"ZustandStoreBrowser.d.ts","sourceRoot":"","sources":["../../../../src/zustand/components/ZustandStoreBrowser.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAUH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAIjD,UAAU,wBAAwB;IAChC,MAAM,EAAE,gBAAgB,EAAE,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,8DAA8D;IAC9D,WAAW,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CAC1C;AA4DD,wBAAgB,mBAAmB,CAAC,EAClC,MAAM,EACN,WAAW,EACX,SAAiB,EACjB,WAAW,GACZ,EAAE,wBAAwB,+BAgG1B"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@buoy-gg/zustand",
|
|
3
|
-
"version": "7.0.
|
|
3
|
+
"version": "7.0.33",
|
|
4
4
|
"description": "Zustand devtools inside your React Native app — state diffs, jump-to-state & one-tap store reset, no middleware. Part of Buoy devtools.",
|
|
5
5
|
"main": "lib/commonjs/index.js",
|
|
6
6
|
"module": "lib/module/index.js",
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
"**/snapshotProvider.ts"
|
|
30
30
|
],
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@buoy-gg/
|
|
33
|
-
"@buoy-gg/
|
|
32
|
+
"@buoy-gg/shared-ui": "^7.0.33",
|
|
33
|
+
"@buoy-gg/license": "^7.0.33"
|
|
34
34
|
},
|
|
35
35
|
"peerDependencies": {
|
|
36
36
|
"react": "*",
|