@buoy-gg/zustand 2.1.12 → 2.1.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/lib/commonjs/index.js +1 -91
  2. package/lib/commonjs/preset.js +1 -102
  3. package/lib/commonjs/zustand/components/ZustandActionButton.js +1 -116
  4. package/lib/commonjs/zustand/components/ZustandDetailViewToggle.js +1 -134
  5. package/lib/commonjs/zustand/components/ZustandEventFilterView.js +1 -291
  6. package/lib/commonjs/zustand/components/ZustandIcon.js +1 -35
  7. package/lib/commonjs/zustand/components/ZustandModal.js +1 -603
  8. package/lib/commonjs/zustand/components/ZustandStateChangeItem.js +1 -165
  9. package/lib/commonjs/zustand/components/ZustandStateDetailContent.js +1 -352
  10. package/lib/commonjs/zustand/components/ZustandStateInfoView.js +1 -508
  11. package/lib/commonjs/zustand/components/ZustandStoreBrowser.js +1 -307
  12. package/lib/commonjs/zustand/components/index.js +1 -73
  13. package/lib/commonjs/zustand/hooks/index.js +1 -12
  14. package/lib/commonjs/zustand/hooks/useZustandStateChanges.js +1 -92
  15. package/lib/commonjs/zustand/index.js +1 -99
  16. package/lib/commonjs/zustand/utils/buoyZustandMiddleware.js +1 -220
  17. package/lib/commonjs/zustand/utils/index.js +1 -31
  18. package/lib/commonjs/zustand/utils/zustandStateStore.js +1 -361
  19. package/lib/module/index.js +1 -80
  20. package/lib/module/preset.js +1 -98
  21. package/lib/module/zustand/components/ZustandActionButton.js +1 -112
  22. package/lib/module/zustand/components/ZustandDetailViewToggle.js +1 -129
  23. package/lib/module/zustand/components/ZustandEventFilterView.js +1 -287
  24. package/lib/module/zustand/components/ZustandIcon.js +1 -32
  25. package/lib/module/zustand/components/ZustandModal.js +1 -599
  26. package/lib/module/zustand/components/ZustandStateChangeItem.js +1 -161
  27. package/lib/module/zustand/components/ZustandStateDetailContent.js +1 -348
  28. package/lib/module/zustand/components/ZustandStateInfoView.js +1 -503
  29. package/lib/module/zustand/components/ZustandStoreBrowser.js +1 -303
  30. package/lib/module/zustand/components/index.js +1 -10
  31. package/lib/module/zustand/hooks/index.js +1 -3
  32. package/lib/module/zustand/hooks/useZustandStateChanges.js +1 -88
  33. package/lib/module/zustand/index.js +1 -12
  34. package/lib/module/zustand/utils/buoyZustandMiddleware.js +1 -214
  35. package/lib/module/zustand/utils/index.js +1 -4
  36. package/lib/module/zustand/utils/zustandStateStore.js +1 -357
  37. package/package.json +3 -3
  38. package/lib/typescript/index.d.ts.map +0 -1
  39. package/lib/typescript/preset.d.ts.map +0 -1
  40. package/lib/typescript/zustand/components/ZustandActionButton.d.ts.map +0 -1
  41. package/lib/typescript/zustand/components/ZustandDetailViewToggle.d.ts.map +0 -1
  42. package/lib/typescript/zustand/components/ZustandEventFilterView.d.ts.map +0 -1
  43. package/lib/typescript/zustand/components/ZustandIcon.d.ts.map +0 -1
  44. package/lib/typescript/zustand/components/ZustandModal.d.ts.map +0 -1
  45. package/lib/typescript/zustand/components/ZustandStateChangeItem.d.ts.map +0 -1
  46. package/lib/typescript/zustand/components/ZustandStateDetailContent.d.ts.map +0 -1
  47. package/lib/typescript/zustand/components/ZustandStateInfoView.d.ts.map +0 -1
  48. package/lib/typescript/zustand/components/ZustandStoreBrowser.d.ts.map +0 -1
  49. package/lib/typescript/zustand/components/index.d.ts.map +0 -1
  50. package/lib/typescript/zustand/hooks/index.d.ts.map +0 -1
  51. package/lib/typescript/zustand/hooks/useZustandStateChanges.d.ts.map +0 -1
  52. package/lib/typescript/zustand/index.d.ts.map +0 -1
  53. package/lib/typescript/zustand/types/index.d.ts.map +0 -1
  54. package/lib/typescript/zustand/utils/buoyZustandMiddleware.d.ts.map +0 -1
  55. package/lib/typescript/zustand/utils/index.d.ts.map +0 -1
  56. package/lib/typescript/zustand/utils/zustandStateStore.d.ts.map +0 -1
@@ -1,161 +1 @@
1
- "use strict";
2
-
3
- /**
4
- * Compact list item for displaying a Zustand state change
5
- *
6
- * Mirrors ReduxActionItem.tsx - uses shared CompactRow for consistent styling
7
- */
8
-
9
- import { View, Text, StyleSheet } from "react-native";
10
- import { CompactRow, buoyColors, Zap, Clock, useRelativeTime } from "@buoy-gg/shared-ui";
11
- import { zustandStateStore } from "../utils/zustandStateStore";
12
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
13
- /**
14
- * Get status label based on category
15
- */
16
- function getStatusLabel(category, storeName) {
17
- switch (category) {
18
- case "replace":
19
- return "Replace";
20
- case "persist":
21
- return "Hydrate";
22
- case "initial":
23
- return "Initial";
24
- default:
25
- return storeName.charAt(0).toUpperCase() + storeName.slice(1);
26
- }
27
- }
28
-
29
- /**
30
- * Get color for category
31
- */
32
- function getCategoryColor(category, storeName) {
33
- switch (category) {
34
- case "replace":
35
- return buoyColors.warning;
36
- case "persist":
37
- return buoyColors.info;
38
- case "initial":
39
- return buoyColors.textMuted;
40
- default:
41
- return zustandStateStore.getStoreColor(storeName);
42
- }
43
- }
44
-
45
- /**
46
- * Get sublabel with duration and diff info
47
- */
48
- function getSublabel(change) {
49
- const parts = [];
50
- if (change.duration !== undefined && change.duration >= 0.1) {
51
- parts.push(`${change.duration.toFixed(1)}ms`);
52
- }
53
- if (change.hasStateChange) {
54
- if (change.changedKeysCount > 0) {
55
- parts.push(`${change.changedKeysCount} key${change.changedKeysCount > 1 ? "s" : ""} changed`);
56
- } else {
57
- parts.push(change.diffSummary || "state changed");
58
- }
59
- } else {
60
- parts.push("no state change");
61
- }
62
- return parts.join(" \u00B7 ");
63
- }
64
-
65
- /**
66
- * Get badge text for the change
67
- */
68
- function getBadgeText(change) {
69
- if (change.category === "replace") return "REPLACE";
70
- if (change.category === "persist") return "HYDRATE";
71
- if (change.category === "initial") return "INIT";
72
- return "SET";
73
- }
74
-
75
- /**
76
- * Get primary display text
77
- */
78
- function getPrimaryText(change) {
79
- if (change.changedKeys.length > 0 && change.changedKeys.length <= 3) {
80
- return change.changedKeys.join(", ");
81
- }
82
- if (change.changedKeys.length > 3) {
83
- return `${change.changedKeys.slice(0, 2).join(", ")} +${change.changedKeys.length - 2}`;
84
- }
85
- return change.partialPreview || "setState()";
86
- }
87
- export function ZustandStateChangeItem({
88
- change,
89
- onPress
90
- }) {
91
- const statusColor = getCategoryColor(change.category, change.storeName);
92
- const statusLabel = getStatusLabel(change.category, change.storeName);
93
- const sublabel = getSublabel(change);
94
- const primaryText = getPrimaryText(change);
95
- const badgeText = getBadgeText(change);
96
- const relativeTime = useRelativeTime(change.timestamp);
97
- let customBadge = undefined;
98
- if (change.isSlowUpdate) {
99
- customBadge = /*#__PURE__*/_jsxs(View, {
100
- style: styles.badgeContainer,
101
- children: [/*#__PURE__*/_jsx(Text, {
102
- style: [styles.badgeText, {
103
- color: statusColor
104
- }],
105
- children: badgeText
106
- }), /*#__PURE__*/_jsx(View, {
107
- style: styles.slowBadge,
108
- children: /*#__PURE__*/_jsx(Clock, {
109
- size: 12,
110
- color: buoyColors.error
111
- })
112
- })]
113
- });
114
- } else if (change.hasStateChange) {
115
- customBadge = /*#__PURE__*/_jsxs(View, {
116
- style: styles.badgeContainer,
117
- children: [/*#__PURE__*/_jsx(Text, {
118
- style: [styles.badgeText, {
119
- color: statusColor
120
- }],
121
- children: badgeText
122
- }), /*#__PURE__*/_jsx(View, {
123
- style: styles.changeBadge,
124
- children: /*#__PURE__*/_jsx(Zap, {
125
- size: 12,
126
- color: buoyColors.warning
127
- })
128
- })]
129
- });
130
- }
131
- return /*#__PURE__*/_jsx(CompactRow, {
132
- statusDotColor: statusColor,
133
- statusLabel: statusLabel,
134
- statusSublabel: sublabel,
135
- primaryText: primaryText,
136
- bottomRightText: relativeTime,
137
- customBadge: customBadge,
138
- badgeText: customBadge ? undefined : badgeText,
139
- badgeColor: statusColor,
140
- showChevron: true,
141
- onPress: () => onPress(change)
142
- });
143
- }
144
- const styles = StyleSheet.create({
145
- badgeContainer: {
146
- flexDirection: "row",
147
- alignItems: "center",
148
- gap: 4
149
- },
150
- badgeText: {
151
- fontSize: 11,
152
- fontWeight: "600",
153
- fontFamily: "monospace"
154
- },
155
- changeBadge: {
156
- paddingHorizontal: 4
157
- },
158
- slowBadge: {
159
- paddingHorizontal: 4
160
- }
161
- });
1
+ "use strict";import{View,Text,StyleSheet}from"react-native";import{CompactRow,buoyColors,Zap,Clock,useRelativeTime}from"@buoy-gg/shared-ui";import{zustandStateStore}from"../utils/zustandStateStore";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";function getStatusLabel(e,t){switch(e){case"replace":return"Replace";case"persist":return"Hydrate";case"initial":return"Initial";default:return t.charAt(0).toUpperCase()+t.slice(1)}}function getCategoryColor(e,t){switch(e){case"replace":return buoyColors.warning;case"persist":return buoyColors.info;case"initial":return buoyColors.textMuted;default:return zustandStateStore.getStoreColor(t)}}function getSublabel(e){const t=[];return void 0!==e.duration&&e.duration>=.1&&t.push(`${e.duration.toFixed(1)}ms`),e.hasStateChange?e.changedKeysCount>0?t.push(`${e.changedKeysCount} key${e.changedKeysCount>1?"s":""} changed`):t.push(e.diffSummary||"state changed"):t.push("no state change"),t.join(" · ")}function getBadgeText(e){return"replace"===e.category?"REPLACE":"persist"===e.category?"HYDRATE":"initial"===e.category?"INIT":"SET"}function getPrimaryText(e){return e.changedKeys.length>0&&e.changedKeys.length<=3?e.changedKeys.join(", "):e.changedKeys.length>3?`${e.changedKeys.slice(0,2).join(", ")} +${e.changedKeys.length-2}`:e.partialPreview||"setState()"}export function ZustandStateChangeItem({change:e,onPress:t}){const a=getCategoryColor(e.category,e.storeName),s=getStatusLabel(e.category,e.storeName),o=getSublabel(e),r=getPrimaryText(e),n=getBadgeText(e),i=useRelativeTime(e.timestamp);let l;return e.isSlowUpdate?l=_jsxs(View,{style:styles.badgeContainer,children:[_jsx(Text,{style:[styles.badgeText,{color:a}],children:n}),_jsx(View,{style:styles.slowBadge,children:_jsx(Clock,{size:12,color:buoyColors.error})})]}):e.hasStateChange&&(l=_jsxs(View,{style:styles.badgeContainer,children:[_jsx(Text,{style:[styles.badgeText,{color:a}],children:n}),_jsx(View,{style:styles.changeBadge,children:_jsx(Zap,{size:12,color:buoyColors.warning})})]})),_jsx(CompactRow,{statusDotColor:a,statusLabel:s,statusSublabel:o,primaryText:r,bottomRightText:i,customBadge:l,badgeText:l?void 0:n,badgeColor:a,showChevron:!0,onPress:()=>t(e)})}const styles=StyleSheet.create({badgeContainer:{flexDirection:"row",alignItems:"center",gap:4},badgeText:{fontSize:11,fontWeight:"600",fontFamily:"monospace"},changeBadge:{paddingHorizontal:4},slowBadge:{paddingHorizontal:4}});
@@ -1,348 +1 @@
1
- "use strict";
2
-
3
- /**
4
- * ZustandStateDetailContent
5
- *
6
- * Detail view for a Zustand state change with 3 view modes:
7
- * - CHANGE: View change details, partial, metadata
8
- * - STATE: View current state after change
9
- * - DIFF: Compare prev vs next state
10
- *
11
- * Mirrors ReduxActionDetailContent.tsx
12
- */
13
-
14
- import { View, Text, StyleSheet, ScrollView } from "react-native";
15
- import { useState, useCallback, useMemo } from "react";
16
- import { macOSColors, EventStepperFooter, formatRelativeTime, parseValue } from "@buoy-gg/shared-ui";
17
- import { DataViewer, SplitDiffViewer, TreeDiffViewer, diffThemes } from "@buoy-gg/shared-ui/dataViewer";
18
- import { ZustandDetailViewToggle } from "./ZustandDetailViewToggle";
19
- import { ZustandStateInfoView } from "./ZustandStateInfoView";
20
- import { DiffModeTabs, CompareBar } from "@buoy-gg/shared-ui";
21
- import { zustandStateStore } from "../utils/zustandStateStore";
22
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
23
- function getChangeColor(change) {
24
- return zustandStateStore.getStoreColor(change.storeName);
25
- }
26
- function getChangeLabel(change) {
27
- switch (change.category) {
28
- case "replace":
29
- return "REPLACE";
30
- case "persist":
31
- return "HYDRATE";
32
- case "initial":
33
- return "INIT";
34
- default:
35
- return "SET";
36
- }
37
- }
38
- function getValueType(value) {
39
- if (value === null) return "null";
40
- if (value === undefined) return "undefined";
41
- if (Array.isArray(value)) return "array";
42
- return typeof value;
43
- }
44
- function formatTimestamp(timestamp) {
45
- const date = new Date(timestamp);
46
- return date.toLocaleTimeString("en-US", {
47
- hour12: false,
48
- hour: "2-digit",
49
- minute: "2-digit",
50
- second: "2-digit"
51
- });
52
- }
53
- const DIFF_MODE_TABS = [{
54
- key: "tree",
55
- label: "TREE VIEW"
56
- }, {
57
- key: "split",
58
- label: "SPLIT VIEW"
59
- }];
60
- export function ZustandStateDetailContent({
61
- change,
62
- changes,
63
- selectedIndex,
64
- onIndexChange,
65
- disableInternalFooter = false
66
- }) {
67
- const [activeView, setActiveView] = useState("change");
68
- const [diffMode, setDiffMode] = useState("tree");
69
- const totalChanges = changes.length;
70
- const changeColor = getChangeColor(change);
71
- const changeLabel = getChangeLabel(change);
72
- const stateType = getValueType(parseValue(change.nextState));
73
-
74
- // Changes are in reverse chronological order (newest first)
75
- const chronologicalNumber = totalChanges - selectedIndex;
76
- const prevChronologicalNumber = chronologicalNumber - 1;
77
- const prevChangeIndex = selectedIndex < totalChanges - 1 ? selectedIndex + 1 : null;
78
- const prevChange = prevChangeIndex !== null ? changes[prevChangeIndex] : null;
79
-
80
- // Compare bar info
81
- const leftEvent = useMemo(() => ({
82
- index: prevChangeIndex ?? 0,
83
- label: prevChronologicalNumber > 0 ? `#${prevChronologicalNumber}` : "Initial",
84
- timestamp: prevChange ? formatTimestamp(prevChange.timestamp) : "",
85
- relativeTime: prevChange ? formatRelativeTime(new Date(prevChange.timestamp)) : "state",
86
- badge: prevChange ? /*#__PURE__*/_jsx(View, {
87
- style: [styles.changeBadgeSmall, {
88
- backgroundColor: `${getChangeColor(prevChange)}20`
89
- }],
90
- children: /*#__PURE__*/_jsx(Text, {
91
- style: [styles.changeTextSmall, {
92
- color: getChangeColor(prevChange)
93
- }],
94
- children: getChangeLabel(prevChange)
95
- })
96
- }) : undefined
97
- }), [prevChangeIndex, prevChange, prevChronologicalNumber]);
98
- const rightEvent = useMemo(() => ({
99
- index: selectedIndex,
100
- label: `#${chronologicalNumber}`,
101
- timestamp: formatTimestamp(change.timestamp),
102
- relativeTime: formatRelativeTime(new Date(change.timestamp)),
103
- badge: /*#__PURE__*/_jsx(View, {
104
- style: [styles.changeBadgeSmall, {
105
- backgroundColor: `${changeColor}20`
106
- }],
107
- children: /*#__PURE__*/_jsx(Text, {
108
- style: [styles.changeTextSmall, {
109
- color: changeColor
110
- }],
111
- children: changeLabel
112
- })
113
- })
114
- }), [selectedIndex, change.timestamp, changeColor, changeLabel, chronologicalNumber]);
115
- const renderStateView = useCallback(() => {
116
- const parsed = parseValue(change.nextState);
117
- return /*#__PURE__*/_jsxs(View, {
118
- style: styles.contentCard,
119
- children: [/*#__PURE__*/_jsxs(View, {
120
- style: styles.valueHeader,
121
- children: [/*#__PURE__*/_jsx(Text, {
122
- style: styles.valueLabel,
123
- children: "STATE AFTER CHANGE"
124
- }), /*#__PURE__*/_jsxs(View, {
125
- style: styles.valueHeaderBadges,
126
- children: [/*#__PURE__*/_jsx(View, {
127
- style: [styles.changeBadge, {
128
- backgroundColor: `${changeColor}20`
129
- }],
130
- children: /*#__PURE__*/_jsx(Text, {
131
- style: [styles.changeText, {
132
- color: changeColor
133
- }],
134
- children: changeLabel
135
- })
136
- }), /*#__PURE__*/_jsx(View, {
137
- style: styles.typeBadge,
138
- children: /*#__PURE__*/_jsx(Text, {
139
- style: styles.typeText,
140
- children: stateType.toUpperCase()
141
- })
142
- })]
143
- })]
144
- }), /*#__PURE__*/_jsx(View, {
145
- style: styles.dataViewerContainer,
146
- children: /*#__PURE__*/_jsx(DataViewer, {
147
- title: "",
148
- data: parsed,
149
- showTypeFilter: true,
150
- rawMode: true,
151
- initialExpanded: true
152
- })
153
- })]
154
- });
155
- }, [change.nextState, changeColor, changeLabel, stateType]);
156
- const renderDiffContent = useCallback(() => {
157
- const prevState = parseValue(change.prevState);
158
- const nextState = parseValue(change.nextState);
159
- if (diffMode === "split") {
160
- return /*#__PURE__*/_jsx(ScrollView, {
161
- style: {
162
- flex: 1
163
- },
164
- showsVerticalScrollIndicator: true,
165
- children: /*#__PURE__*/_jsx(SplitDiffViewer, {
166
- oldValue: prevState,
167
- newValue: nextState,
168
- theme: diffThemes.devToolsDefault,
169
- options: {
170
- hideLineNumbers: false,
171
- disableWordDiff: false,
172
- showDiffOnly: false,
173
- compareMethod: "words",
174
- contextLines: 3
175
- },
176
- showThemeName: false
177
- })
178
- });
179
- }
180
- return /*#__PURE__*/_jsx(TreeDiffViewer, {
181
- oldValue: prevState,
182
- newValue: nextState
183
- });
184
- }, [change.prevState, change.nextState, diffMode]);
185
- const handleFooterPrevious = useCallback(() => {
186
- onIndexChange(Math.min(totalChanges - 1, selectedIndex + 1));
187
- }, [selectedIndex, totalChanges, onIndexChange]);
188
- const handleFooterNext = useCallback(() => {
189
- onIndexChange(Math.max(0, selectedIndex - 1));
190
- }, [selectedIndex, onIndexChange]);
191
- const diffDisabled = totalChanges <= 1;
192
- return /*#__PURE__*/_jsxs(View, {
193
- style: styles.container,
194
- children: [/*#__PURE__*/_jsx(ZustandDetailViewToggle, {
195
- activeView: activeView,
196
- onViewChange: setActiveView,
197
- diffDisabled: diffDisabled
198
- }), /*#__PURE__*/_jsxs(View, {
199
- style: styles.contentArea,
200
- children: [activeView === "change" && /*#__PURE__*/_jsx(ZustandStateInfoView, {
201
- change: change
202
- }), activeView === "state" && /*#__PURE__*/_jsx(View, {
203
- style: styles.stateContainer,
204
- children: renderStateView()
205
- }), activeView === "diff" && /*#__PURE__*/_jsxs(View, {
206
- style: styles.diffContainer,
207
- children: [/*#__PURE__*/_jsx(DiffModeTabs, {
208
- tabs: DIFF_MODE_TABS,
209
- activeTab: diffMode,
210
- onTabChange: setDiffMode
211
- }), /*#__PURE__*/_jsx(CompareBar, {
212
- leftEvent: leftEvent,
213
- rightEvent: rightEvent
214
- }), /*#__PURE__*/_jsx(View, {
215
- style: styles.diffContent,
216
- children: renderDiffContent()
217
- })]
218
- })]
219
- }), !disableInternalFooter && totalChanges > 1 && /*#__PURE__*/_jsx(EventStepperFooter, {
220
- currentIndex: chronologicalNumber - 1,
221
- totalItems: totalChanges,
222
- onPrevious: handleFooterPrevious,
223
- onNext: handleFooterNext,
224
- itemLabel: "Change",
225
- subtitle: formatRelativeTime(new Date(change.timestamp)),
226
- absolute: true
227
- })]
228
- });
229
- }
230
-
231
- /**
232
- * External footer component for modal use
233
- */
234
- export function ZustandStateDetailFooter({
235
- change,
236
- changes,
237
- selectedIndex,
238
- onIndexChange
239
- }) {
240
- const totalChanges = changes.length;
241
- if (totalChanges <= 1) return null;
242
- const chronologicalNumber = totalChanges - selectedIndex;
243
- return /*#__PURE__*/_jsx(EventStepperFooter, {
244
- currentIndex: chronologicalNumber - 1,
245
- totalItems: totalChanges,
246
- onPrevious: () => onIndexChange(Math.min(totalChanges - 1, selectedIndex + 1)),
247
- onNext: () => onIndexChange(Math.max(0, selectedIndex - 1)),
248
- itemLabel: "Change",
249
- subtitle: formatRelativeTime(new Date(change.timestamp))
250
- });
251
- }
252
- const styles = StyleSheet.create({
253
- container: {
254
- flex: 1,
255
- backgroundColor: macOSColors.background.base
256
- },
257
- contentArea: {
258
- flex: 1,
259
- paddingBottom: 96
260
- },
261
- stateContainer: {
262
- flex: 1,
263
- padding: 14
264
- },
265
- contentCard: {
266
- backgroundColor: macOSColors.background.card,
267
- borderRadius: 14,
268
- padding: 14,
269
- borderWidth: 1,
270
- borderColor: macOSColors.border.default
271
- },
272
- valueHeader: {
273
- flexDirection: "row",
274
- alignItems: "center",
275
- justifyContent: "space-between",
276
- marginBottom: 8
277
- },
278
- valueLabel: {
279
- fontSize: 10,
280
- color: macOSColors.text.secondary,
281
- fontFamily: "monospace",
282
- letterSpacing: 0.5,
283
- fontWeight: "600"
284
- },
285
- valueHeaderBadges: {
286
- flexDirection: "row",
287
- alignItems: "center",
288
- gap: 6
289
- },
290
- changeBadge: {
291
- paddingHorizontal: 8,
292
- paddingVertical: 2,
293
- borderRadius: 4
294
- },
295
- changeText: {
296
- fontSize: 9,
297
- fontWeight: "700",
298
- fontFamily: "monospace",
299
- letterSpacing: 0.3
300
- },
301
- typeBadge: {
302
- paddingHorizontal: 8,
303
- paddingVertical: 2,
304
- borderRadius: 4,
305
- backgroundColor: macOSColors.background.input
306
- },
307
- typeText: {
308
- fontSize: 9,
309
- fontWeight: "600",
310
- color: macOSColors.text.muted,
311
- fontFamily: "monospace"
312
- },
313
- valueBox: {
314
- backgroundColor: macOSColors.background.base,
315
- borderRadius: 6,
316
- borderWidth: 1,
317
- borderColor: macOSColors.border.input,
318
- padding: 8
319
- },
320
- valueText: {
321
- fontSize: 12,
322
- color: macOSColors.text.primary,
323
- fontFamily: "monospace",
324
- lineHeight: 18
325
- },
326
- diffContainer: {
327
- flex: 1
328
- },
329
- diffContent: {
330
- flex: 1,
331
- paddingHorizontal: 14
332
- },
333
- changeBadgeSmall: {
334
- paddingHorizontal: 6,
335
- paddingVertical: 1,
336
- borderRadius: 3
337
- },
338
- changeTextSmall: {
339
- fontSize: 8,
340
- fontWeight: "700",
341
- fontFamily: "monospace"
342
- },
343
- dataViewerContainer: {
344
- marginTop: -12,
345
- marginHorizontal: -12,
346
- marginBottom: -12
347
- }
348
- });
1
+ "use strict";import{View,Text,StyleSheet,ScrollView}from"react-native";import{useState,useCallback,useMemo}from"react";import{macOSColors,EventStepperFooter,formatRelativeTime,parseValue}from"@buoy-gg/shared-ui";import{DataViewer,SplitDiffViewer,TreeDiffViewer,diffThemes}from"@buoy-gg/shared-ui/dataViewer";import{ZustandDetailViewToggle}from"./ZustandDetailViewToggle";import{ZustandStateInfoView}from"./ZustandStateInfoView";import{DiffModeTabs,CompareBar}from"@buoy-gg/shared-ui";import{zustandStateStore}from"../utils/zustandStateStore";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";function getChangeColor(e){return zustandStateStore.getStoreColor(e.storeName)}function getChangeLabel(e){switch(e.category){case"replace":return"REPLACE";case"persist":return"HYDRATE";case"initial":return"INIT";default:return"SET"}}function getValueType(e){return null===e?"null":void 0===e?"undefined":Array.isArray(e)?"array":typeof e}function formatTimestamp(e){return new Date(e).toLocaleTimeString("en-US",{hour12:!1,hour:"2-digit",minute:"2-digit",second:"2-digit"})}const DIFF_MODE_TABS=[{key:"tree",label:"TREE VIEW"},{key:"split",label:"SPLIT VIEW"}];export function ZustandStateDetailContent({change:e,changes:t,selectedIndex:a,onIndexChange:o,disableInternalFooter:n=!1}){const[r,i]=useState("change"),[l,s]=useState("tree"),d=t.length,c=getChangeColor(e),m=getChangeLabel(e),u=getValueType(parseValue(e.nextState)),g=d-a,f=g-1,h=a<d-1?a+1:null,p=null!==h?t[h]:null,x=useMemo(()=>({index:h??0,label:f>0?`#${f}`:"Initial",timestamp:p?formatTimestamp(p.timestamp):"",relativeTime:p?formatRelativeTime(new Date(p.timestamp)):"state",badge:p?_jsx(View,{style:[styles.changeBadgeSmall,{backgroundColor:`${getChangeColor(p)}20`}],children:_jsx(Text,{style:[styles.changeTextSmall,{color:getChangeColor(p)}],children:getChangeLabel(p)})}):void 0}),[h,p,f]),y=useMemo(()=>({index:a,label:`#${g}`,timestamp:formatTimestamp(e.timestamp),relativeTime:formatRelativeTime(new Date(e.timestamp)),badge:_jsx(View,{style:[styles.changeBadgeSmall,{backgroundColor:`${c}20`}],children:_jsx(Text,{style:[styles.changeTextSmall,{color:c}],children:m})})}),[a,e.timestamp,c,m,g]),S=useCallback(()=>{const t=parseValue(e.nextState);return _jsxs(View,{style:styles.contentCard,children:[_jsxs(View,{style:styles.valueHeader,children:[_jsx(Text,{style:styles.valueLabel,children:"STATE AFTER CHANGE"}),_jsxs(View,{style:styles.valueHeaderBadges,children:[_jsx(View,{style:[styles.changeBadge,{backgroundColor:`${c}20`}],children:_jsx(Text,{style:[styles.changeText,{color:c}],children:m})}),_jsx(View,{style:styles.typeBadge,children:_jsx(Text,{style:styles.typeText,children:u.toUpperCase()})})]})]}),_jsx(View,{style:styles.dataViewerContainer,children:_jsx(DataViewer,{title:"",data:t,showTypeFilter:!0,rawMode:!0,initialExpanded:!0})})]})},[e.nextState,c,m,u]),C=useCallback(()=>{const t=parseValue(e.prevState),a=parseValue(e.nextState);return"split"===l?_jsx(ScrollView,{style:{flex:1},showsVerticalScrollIndicator:!0,children:_jsx(SplitDiffViewer,{oldValue:t,newValue:a,theme:diffThemes.devToolsDefault,options:{hideLineNumbers:!1,disableWordDiff:!1,showDiffOnly:!1,compareMethod:"words",contextLines:3},showThemeName:!1})}):_jsx(TreeDiffViewer,{oldValue:t,newValue:a})},[e.prevState,e.nextState,l]),b=useCallback(()=>{o(Math.min(d-1,a+1))},[a,d,o]),T=useCallback(()=>{o(Math.max(0,a-1))},[a,o]),w=d<=1;return _jsxs(View,{style:styles.container,children:[_jsx(ZustandDetailViewToggle,{activeView:r,onViewChange:i,diffDisabled:w}),_jsxs(View,{style:styles.contentArea,children:["change"===r&&_jsx(ZustandStateInfoView,{change:e}),"state"===r&&_jsx(View,{style:styles.stateContainer,children:S()}),"diff"===r&&_jsxs(View,{style:styles.diffContainer,children:[_jsx(DiffModeTabs,{tabs:DIFF_MODE_TABS,activeTab:l,onTabChange:s}),_jsx(CompareBar,{leftEvent:x,rightEvent:y}),_jsx(View,{style:styles.diffContent,children:C()})]})]}),!n&&d>1&&_jsx(EventStepperFooter,{currentIndex:g-1,totalItems:d,onPrevious:b,onNext:T,itemLabel:"Change",subtitle:formatRelativeTime(new Date(e.timestamp)),absolute:!0})]})}export function ZustandStateDetailFooter({change:e,changes:t,selectedIndex:a,onIndexChange:o}){const n=t.length;return n<=1?null:_jsx(EventStepperFooter,{currentIndex:n-a-1,totalItems:n,onPrevious:()=>o(Math.min(n-1,a+1)),onNext:()=>o(Math.max(0,a-1)),itemLabel:"Change",subtitle:formatRelativeTime(new Date(e.timestamp))})}const styles=StyleSheet.create({container:{flex:1,backgroundColor:macOSColors.background.base},contentArea:{flex:1,paddingBottom:96},stateContainer:{flex:1,padding:14},contentCard:{backgroundColor:macOSColors.background.card,borderRadius:14,padding:14,borderWidth:1,borderColor:macOSColors.border.default},valueHeader:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",marginBottom:8},valueLabel:{fontSize:10,color:macOSColors.text.secondary,fontFamily:"monospace",letterSpacing:.5,fontWeight:"600"},valueHeaderBadges:{flexDirection:"row",alignItems:"center",gap:6},changeBadge:{paddingHorizontal:8,paddingVertical:2,borderRadius:4},changeText:{fontSize:9,fontWeight:"700",fontFamily:"monospace",letterSpacing:.3},typeBadge:{paddingHorizontal:8,paddingVertical:2,borderRadius:4,backgroundColor:macOSColors.background.input},typeText:{fontSize:9,fontWeight:"600",color:macOSColors.text.muted,fontFamily:"monospace"},valueBox:{backgroundColor:macOSColors.background.base,borderRadius:6,borderWidth:1,borderColor:macOSColors.border.input,padding:8},valueText:{fontSize:12,color:macOSColors.text.primary,fontFamily:"monospace",lineHeight:18},diffContainer:{flex:1},diffContent:{flex:1,paddingHorizontal:14},changeBadgeSmall:{paddingHorizontal:6,paddingVertical:1,borderRadius:3},changeTextSmall:{fontSize:8,fontWeight:"700",fontFamily:"monospace"},dataViewerContainer:{marginTop:-12,marginHorizontal:-12,marginBottom:-12}});