@buoy-gg/jotai 2.1.10 → 2.1.12

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 (41) hide show
  1. package/lib/commonjs/index.js +91 -1
  2. package/lib/commonjs/jotai/components/JotaiAtomBrowser.js +300 -1
  3. package/lib/commonjs/jotai/components/JotaiAtomChangeItem.js +113 -1
  4. package/lib/commonjs/jotai/components/JotaiAtomDetailContent.js +754 -1
  5. package/lib/commonjs/jotai/components/JotaiEventFilterView.js +305 -1
  6. package/lib/commonjs/jotai/components/JotaiIcon.js +35 -1
  7. package/lib/commonjs/jotai/components/JotaiModal.js +567 -1
  8. package/lib/commonjs/jotai/components/index.js +59 -1
  9. package/lib/commonjs/jotai/hooks/useJotaiAtomChanges.js +83 -1
  10. package/lib/commonjs/jotai/index.js +85 -1
  11. package/lib/commonjs/jotai/utils/jotaiStateStore.js +322 -1
  12. package/lib/commonjs/jotai/utils/watchAtoms.js +149 -1
  13. package/lib/commonjs/preset.js +98 -1
  14. package/lib/module/index.js +74 -1
  15. package/lib/module/jotai/components/JotaiAtomBrowser.js +296 -1
  16. package/lib/module/jotai/components/JotaiAtomChangeItem.js +109 -1
  17. package/lib/module/jotai/components/JotaiAtomDetailContent.js +748 -1
  18. package/lib/module/jotai/components/JotaiEventFilterView.js +301 -1
  19. package/lib/module/jotai/components/JotaiIcon.js +31 -1
  20. package/lib/module/jotai/components/JotaiModal.js +563 -1
  21. package/lib/module/jotai/components/index.js +8 -1
  22. package/lib/module/jotai/hooks/useJotaiAtomChanges.js +79 -1
  23. package/lib/module/jotai/index.js +10 -1
  24. package/lib/module/jotai/utils/jotaiStateStore.js +318 -1
  25. package/lib/module/jotai/utils/watchAtoms.js +144 -1
  26. package/lib/module/preset.js +94 -1
  27. package/lib/typescript/index.d.ts.map +1 -0
  28. package/lib/typescript/jotai/components/JotaiAtomBrowser.d.ts.map +1 -0
  29. package/lib/typescript/jotai/components/JotaiAtomChangeItem.d.ts.map +1 -0
  30. package/lib/typescript/jotai/components/JotaiAtomDetailContent.d.ts.map +1 -0
  31. package/lib/typescript/jotai/components/JotaiEventFilterView.d.ts.map +1 -0
  32. package/lib/typescript/jotai/components/JotaiIcon.d.ts.map +1 -0
  33. package/lib/typescript/jotai/components/JotaiModal.d.ts.map +1 -0
  34. package/lib/typescript/jotai/components/index.d.ts.map +1 -0
  35. package/lib/typescript/jotai/hooks/useJotaiAtomChanges.d.ts.map +1 -0
  36. package/lib/typescript/jotai/index.d.ts.map +1 -0
  37. package/lib/typescript/jotai/types/index.d.ts.map +1 -0
  38. package/lib/typescript/jotai/utils/jotaiStateStore.d.ts.map +1 -0
  39. package/lib/typescript/jotai/utils/watchAtoms.d.ts.map +1 -0
  40. package/lib/typescript/preset.d.ts.map +1 -0
  41. package/package.json +3 -3
@@ -1 +1,91 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),Object.defineProperty(exports,"JOTAI_ICON_COLOR",{enumerable:!0,get:function(){return _JotaiIcon.JOTAI_ICON_COLOR}}),Object.defineProperty(exports,"JotaiAtomChangeItem",{enumerable:!0,get:function(){return _JotaiAtomChangeItem.JotaiAtomChangeItem}}),Object.defineProperty(exports,"JotaiAtomDetailContent",{enumerable:!0,get:function(){return _JotaiAtomDetailContent.JotaiAtomDetailContent}}),Object.defineProperty(exports,"JotaiAtomDetailFooter",{enumerable:!0,get:function(){return _JotaiAtomDetailContent.JotaiAtomDetailFooter}}),Object.defineProperty(exports,"JotaiIcon",{enumerable:!0,get:function(){return _JotaiIcon.JotaiIcon}}),Object.defineProperty(exports,"JotaiModal",{enumerable:!0,get:function(){return _JotaiModal.JotaiModal}}),Object.defineProperty(exports,"createJotaiTool",{enumerable:!0,get:function(){return _preset.createJotaiTool}}),Object.defineProperty(exports,"isAtomWatched",{enumerable:!0,get:function(){return _watchAtoms.isAtomWatched}}),Object.defineProperty(exports,"jotaiStateStore",{enumerable:!0,get:function(){return _jotaiStateStore.jotaiStateStore}}),Object.defineProperty(exports,"jotaiToolPreset",{enumerable:!0,get:function(){return _preset.jotaiToolPreset}}),Object.defineProperty(exports,"useJotaiAtomChanges",{enumerable:!0,get:function(){return _useJotaiAtomChanges.useJotaiAtomChanges}}),Object.defineProperty(exports,"watchAtoms",{enumerable:!0,get:function(){return _watchAtoms.watchAtoms}}),Object.defineProperty(exports,"watchDefaultStoreAtoms",{enumerable:!0,get:function(){return _watchAtoms.watchDefaultStoreAtoms}});var _preset=require("./preset"),_watchAtoms=require("./jotai/utils/watchAtoms"),_useJotaiAtomChanges=require("./jotai/hooks/useJotaiAtomChanges"),_JotaiModal=require("./jotai/components/JotaiModal"),_JotaiAtomChangeItem=require("./jotai/components/JotaiAtomChangeItem"),_JotaiAtomDetailContent=require("./jotai/components/JotaiAtomDetailContent"),_JotaiIcon=require("./jotai/components/JotaiIcon"),_jotaiStateStore=require("./jotai/utils/jotaiStateStore");
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ Object.defineProperty(exports, "JOTAI_ICON_COLOR", {
7
+ enumerable: true,
8
+ get: function () {
9
+ return _JotaiIcon.JOTAI_ICON_COLOR;
10
+ }
11
+ });
12
+ Object.defineProperty(exports, "JotaiAtomChangeItem", {
13
+ enumerable: true,
14
+ get: function () {
15
+ return _JotaiAtomChangeItem.JotaiAtomChangeItem;
16
+ }
17
+ });
18
+ Object.defineProperty(exports, "JotaiAtomDetailContent", {
19
+ enumerable: true,
20
+ get: function () {
21
+ return _JotaiAtomDetailContent.JotaiAtomDetailContent;
22
+ }
23
+ });
24
+ Object.defineProperty(exports, "JotaiAtomDetailFooter", {
25
+ enumerable: true,
26
+ get: function () {
27
+ return _JotaiAtomDetailContent.JotaiAtomDetailFooter;
28
+ }
29
+ });
30
+ Object.defineProperty(exports, "JotaiIcon", {
31
+ enumerable: true,
32
+ get: function () {
33
+ return _JotaiIcon.JotaiIcon;
34
+ }
35
+ });
36
+ Object.defineProperty(exports, "JotaiModal", {
37
+ enumerable: true,
38
+ get: function () {
39
+ return _JotaiModal.JotaiModal;
40
+ }
41
+ });
42
+ Object.defineProperty(exports, "createJotaiTool", {
43
+ enumerable: true,
44
+ get: function () {
45
+ return _preset.createJotaiTool;
46
+ }
47
+ });
48
+ Object.defineProperty(exports, "isAtomWatched", {
49
+ enumerable: true,
50
+ get: function () {
51
+ return _watchAtoms.isAtomWatched;
52
+ }
53
+ });
54
+ Object.defineProperty(exports, "jotaiStateStore", {
55
+ enumerable: true,
56
+ get: function () {
57
+ return _jotaiStateStore.jotaiStateStore;
58
+ }
59
+ });
60
+ Object.defineProperty(exports, "jotaiToolPreset", {
61
+ enumerable: true,
62
+ get: function () {
63
+ return _preset.jotaiToolPreset;
64
+ }
65
+ });
66
+ Object.defineProperty(exports, "useJotaiAtomChanges", {
67
+ enumerable: true,
68
+ get: function () {
69
+ return _useJotaiAtomChanges.useJotaiAtomChanges;
70
+ }
71
+ });
72
+ Object.defineProperty(exports, "watchAtoms", {
73
+ enumerable: true,
74
+ get: function () {
75
+ return _watchAtoms.watchAtoms;
76
+ }
77
+ });
78
+ Object.defineProperty(exports, "watchDefaultStoreAtoms", {
79
+ enumerable: true,
80
+ get: function () {
81
+ return _watchAtoms.watchDefaultStoreAtoms;
82
+ }
83
+ });
84
+ var _preset = require("./preset");
85
+ var _watchAtoms = require("./jotai/utils/watchAtoms");
86
+ var _useJotaiAtomChanges = require("./jotai/hooks/useJotaiAtomChanges");
87
+ var _JotaiModal = require("./jotai/components/JotaiModal");
88
+ var _JotaiAtomChangeItem = require("./jotai/components/JotaiAtomChangeItem");
89
+ var _JotaiAtomDetailContent = require("./jotai/components/JotaiAtomDetailContent");
90
+ var _JotaiIcon = require("./jotai/components/JotaiIcon");
91
+ var _jotaiStateStore = require("./jotai/utils/jotaiStateStore");
@@ -1 +1,300 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.JotaiAtomBrowser=JotaiAtomBrowser;var _react=require("react"),_reactNative=require("react-native"),_sharedUi=require("@buoy-gg/shared-ui"),_dataViewer=require("@buoy-gg/shared-ui/dataViewer"),_jotaiStateStore=require("../utils/jotaiStateStore"),_jsxRuntime=require("react/jsx-runtime");function getValuePreview(e){try{const t=e.getValue();if(void 0===t)return"undefined";if(null===t)return"null";if(Array.isArray(t))return 0===t.length?"[]":`[${t.length} item${1===t.length?"":"s"}]`;if("object"==typeof t){const e=Object.keys(t);return 0===e.length?"{}":e.length<=3?e.join(", "):`${e.slice(0,2).join(", ")} +${e.length-2}`}return String(t).slice(0,40)}catch{return""}}function getValueType(e){try{const t=e.getValue();return null===t?"null":void 0===t?"undefined":Array.isArray(t)?`array · ${t.length}`:typeof t}catch{return"unknown"}}function AtomExpandedContent({atom:e,onViewHistory:t}){const r=e.getValue(),i=(0,_react.useMemo)(()=>{if(r&&"object"==typeof r){const e={};for(const[t,i]of Object.entries(r))"function"!=typeof i&&(e[t]=i);return(0,_sharedUi.parseValue)(e)}return(0,_sharedUi.parseValue)(r)},[r]);return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:expandedStyles.container,children:[(0,_jsxRuntime.jsx)(_sharedUi.ExpandedInfoRow,{label:"Type",children:(0,_jsxRuntime.jsx)(_sharedUi.PillBadge,{color:e.color,children:"JOTAI"})}),e.changeCount>0&&(0,_jsxRuntime.jsxs)(_sharedUi.ExpandedInfoRow,{label:"Changes",children:[(0,_jsxRuntime.jsx)(_sharedUi.PillBadge,{color:_sharedUi.buoyColors.warning,children:String(e.changeCount)}),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{onPress:()=>t(e.label),style:expandedStyles.viewHistoryButton,hitSlop:{top:6,bottom:6,left:6,right:6},children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[expandedStyles.viewHistoryText,{color:e.color}],children:"view history →"})})]}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:expandedStyles.dataContainer,children:i&&"object"==typeof i?(0,_jsxRuntime.jsx)(_dataViewer.DataViewer,{title:"",data:i,showTypeFilter:!0}):(0,_jsxRuntime.jsx)(_reactNative.Text,{style:expandedStyles.primitiveText,children:String(r??"undefined")})})]})}function EmptyBrowserState(){return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.emptyState,children:[(0,_jsxRuntime.jsx)(_sharedUi.Box,{size:32,color:_sharedUi.macOSColors.text.muted}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.emptyTitle,children:"No atoms registered"}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.emptyText,children:"Use watchAtoms(store, { atomName }) to register your Jotai atoms.\nThey will appear here with their current value."})]})}function JotaiAtomBrowser({atoms:e,searchQuery:t,onViewHistory:r}){const[i,o]=(0,_react.useState)(null),n=(0,_react.useMemo)(()=>{if(!t)return e;const r=t.toLowerCase();return e.filter(e=>e.label.toLowerCase().includes(r))},[e,t]),a=(0,_react.useCallback)(e=>{o(t=>t===e.label?null:e.label)},[]);return 0!==n.length||t?0===n.length&&t?(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.emptyState,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.emptyTitle,children:"No matching atoms"}),(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.emptyText,children:['No atoms match "',t,'"']})]}):(0,_jsxRuntime.jsxs)(_reactNative.ScrollView,{style:styles.container,contentContainerStyle:styles.scrollContent,showsVerticalScrollIndicator:!0,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.sectionHeader,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.sectionTitle,children:"ATOMS"}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.sectionCountBadge,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.sectionCountText,children:n.length})})]}),n.map(e=>{const t=i===e.label,o=getValuePreview(e),n=_jotaiStateStore.jotaiStateStore.getAtomColor(e.label);return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.atomRowWrapper,children:[(0,_jsxRuntime.jsx)(_sharedUi.CompactRow,{statusDotColor:n,statusLabel:e.label,statusSublabel:getValueType(e),primaryText:o,showChevron:!0,isExpanded:t,onPress:()=>a(e),expandedContent:t?(0,_jsxRuntime.jsx)(AtomExpandedContent,{atom:e,onViewHistory:r}):void 0}),e.changeCount>0&&(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.absCountBadge,{backgroundColor:n+"22",borderColor:n+"55"}],pointerEvents:"none",children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.absCountText,{color:n}],children:String(e.changeCount)})})]},e.label)})]}):(0,_jsxRuntime.jsx)(EmptyBrowserState,{})}const styles=_reactNative.StyleSheet.create({container:{flex:1},atomRowWrapper:{position:"relative"},absCountBadge:{position:"absolute",top:4,right:10,paddingHorizontal:5,paddingVertical:1,borderRadius:4,borderWidth:1,zIndex:1},absCountText:{fontSize:9,fontWeight:"700",fontFamily:"monospace"},scrollContent:{paddingTop:8,paddingBottom:20},sectionHeader:{flexDirection:"row",alignItems:"center",paddingHorizontal:16,paddingVertical:8,gap:8},sectionTitle:{fontSize:11,fontWeight:"700",letterSpacing:.5,color:_sharedUi.macOSColors.text.muted},sectionCountBadge:{backgroundColor:_sharedUi.buoyColors.primary+"26",paddingHorizontal:8,paddingVertical:2,borderRadius:4},sectionCountText:{fontSize:10,fontWeight:"700",color:_sharedUi.buoyColors.primary,fontFamily:"monospace"},emptyState:{alignItems:"center",paddingVertical:40},emptyTitle:{color:_sharedUi.macOSColors.text.primary,fontSize:14,fontWeight:"600",marginTop:12,marginBottom:6},emptyText:{color:_sharedUi.macOSColors.text.muted,fontSize:12,textAlign:"center",lineHeight:18}}),expandedStyles=_reactNative.StyleSheet.create({container:{gap:10},viewHistoryButton:{marginLeft:4},viewHistoryText:{fontSize:10,fontWeight:"600",fontFamily:"monospace"},dataContainer:{backgroundColor:_sharedUi.buoyColors.base,borderRadius:6,borderWidth:1,borderColor:_sharedUi.buoyColors.border,overflow:"hidden",minHeight:60},primitiveText:{color:_sharedUi.buoyColors.text,fontSize:12,fontFamily:"monospace",padding:14}});
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.JotaiAtomBrowser = JotaiAtomBrowser;
7
+ var _react = require("react");
8
+ var _reactNative = require("react-native");
9
+ var _sharedUi = require("@buoy-gg/shared-ui");
10
+ var _dataViewer = require("@buoy-gg/shared-ui/dataViewer");
11
+ var _jotaiStateStore = require("../utils/jotaiStateStore");
12
+ var _jsxRuntime = require("react/jsx-runtime");
13
+ /**
14
+ * JotaiAtomBrowser
15
+ *
16
+ * Atoms tab — shows all registered Jotai atoms and their current value.
17
+ * Mirrors ZustandStoreBrowser.tsx from @buoy-gg/zustand.
18
+ */
19
+
20
+ function getValuePreview(atom) {
21
+ try {
22
+ const value = atom.getValue();
23
+ if (value === undefined) return "undefined";
24
+ if (value === null) return "null";
25
+ if (Array.isArray(value)) {
26
+ if (value.length === 0) return "[]";
27
+ return `[${value.length} item${value.length === 1 ? "" : "s"}]`;
28
+ }
29
+ if (typeof value === "object") {
30
+ const keys = Object.keys(value);
31
+ if (keys.length === 0) return "{}";
32
+ if (keys.length <= 3) return keys.join(", ");
33
+ return `${keys.slice(0, 2).join(", ")} +${keys.length - 2}`;
34
+ }
35
+ return String(value).slice(0, 40);
36
+ } catch {
37
+ return "";
38
+ }
39
+ }
40
+ function getValueType(atom) {
41
+ try {
42
+ const value = atom.getValue();
43
+ if (value === null) return "null";
44
+ if (value === undefined) return "undefined";
45
+ if (Array.isArray(value)) return `array · ${value.length}`;
46
+ return typeof value;
47
+ } catch {
48
+ return "unknown";
49
+ }
50
+ }
51
+ function AtomExpandedContent({
52
+ atom,
53
+ onViewHistory
54
+ }) {
55
+ const value = atom.getValue();
56
+ const displayValue = (0, _react.useMemo)(() => {
57
+ if (value && typeof value === "object") {
58
+ const filtered = {};
59
+ for (const [key, v] of Object.entries(value)) {
60
+ if (typeof v !== "function") filtered[key] = v;
61
+ }
62
+ return (0, _sharedUi.parseValue)(filtered);
63
+ }
64
+ return (0, _sharedUi.parseValue)(value);
65
+ }, [value]);
66
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
67
+ style: expandedStyles.container,
68
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ExpandedInfoRow, {
69
+ label: "Type",
70
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.PillBadge, {
71
+ color: atom.color,
72
+ children: "JOTAI"
73
+ })
74
+ }), atom.changeCount > 0 && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_sharedUi.ExpandedInfoRow, {
75
+ label: "Changes",
76
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.PillBadge, {
77
+ color: _sharedUi.buoyColors.warning,
78
+ children: String(atom.changeCount)
79
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
80
+ onPress: () => onViewHistory(atom.label),
81
+ style: expandedStyles.viewHistoryButton,
82
+ hitSlop: {
83
+ top: 6,
84
+ bottom: 6,
85
+ left: 6,
86
+ right: 6
87
+ },
88
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
89
+ style: [expandedStyles.viewHistoryText, {
90
+ color: atom.color
91
+ }],
92
+ children: "view history \u2192"
93
+ })
94
+ })]
95
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
96
+ style: expandedStyles.dataContainer,
97
+ children: displayValue && typeof displayValue === "object" ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_dataViewer.DataViewer, {
98
+ title: "",
99
+ data: displayValue,
100
+ showTypeFilter: true,
101
+ rawMode: true,
102
+ initialExpanded: true
103
+ }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
104
+ style: expandedStyles.primitiveText,
105
+ children: String(value ?? "undefined")
106
+ })
107
+ })]
108
+ });
109
+ }
110
+ function EmptyBrowserState() {
111
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
112
+ style: styles.emptyState,
113
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Box, {
114
+ size: 32,
115
+ color: _sharedUi.macOSColors.text.muted
116
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
117
+ style: styles.emptyTitle,
118
+ children: "No atoms registered"
119
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
120
+ style: styles.emptyText,
121
+ children: "Use watchAtoms(store, { atomName }) to register your Jotai atoms.\nThey will appear here with their current value."
122
+ })]
123
+ });
124
+ }
125
+ function JotaiAtomBrowser({
126
+ atoms,
127
+ searchQuery,
128
+ onViewHistory
129
+ }) {
130
+ const [expandedAtom, setExpandedAtom] = (0, _react.useState)(null);
131
+ const filteredAtoms = (0, _react.useMemo)(() => {
132
+ if (!searchQuery) return atoms;
133
+ const search = searchQuery.toLowerCase();
134
+ return atoms.filter(a => a.label.toLowerCase().includes(search));
135
+ }, [atoms, searchQuery]);
136
+ const handleAtomPress = (0, _react.useCallback)(atom => {
137
+ setExpandedAtom(prev => prev === atom.label ? null : atom.label);
138
+ }, []);
139
+ if (filteredAtoms.length === 0 && !searchQuery) {
140
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(EmptyBrowserState, {});
141
+ }
142
+ if (filteredAtoms.length === 0 && searchQuery) {
143
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
144
+ style: styles.emptyState,
145
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
146
+ style: styles.emptyTitle,
147
+ children: "No matching atoms"
148
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
149
+ style: styles.emptyText,
150
+ children: ["No atoms match \"", searchQuery, "\""]
151
+ })]
152
+ });
153
+ }
154
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.ScrollView, {
155
+ style: styles.container,
156
+ contentContainerStyle: styles.scrollContent,
157
+ showsVerticalScrollIndicator: true,
158
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
159
+ style: styles.sectionHeader,
160
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
161
+ style: styles.sectionTitle,
162
+ children: "ATOMS"
163
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
164
+ style: styles.sectionCountBadge,
165
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
166
+ style: styles.sectionCountText,
167
+ children: filteredAtoms.length
168
+ })
169
+ })]
170
+ }), filteredAtoms.map(atom => {
171
+ const isExpanded = expandedAtom === atom.label;
172
+ const valuePreview = getValuePreview(atom);
173
+ const atomColor = _jotaiStateStore.jotaiStateStore.getAtomColor(atom.label);
174
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
175
+ style: styles.atomRowWrapper,
176
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.CompactRow, {
177
+ statusDotColor: atomColor,
178
+ statusLabel: atom.label,
179
+ statusSublabel: getValueType(atom),
180
+ primaryText: valuePreview,
181
+ showChevron: true,
182
+ isExpanded: isExpanded,
183
+ onPress: () => handleAtomPress(atom),
184
+ expandedContent: isExpanded ? /*#__PURE__*/(0, _jsxRuntime.jsx)(AtomExpandedContent, {
185
+ atom: atom,
186
+ onViewHistory: onViewHistory
187
+ }) : undefined
188
+ }), atom.changeCount > 0 && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
189
+ style: [styles.absCountBadge, {
190
+ backgroundColor: atomColor + "22",
191
+ borderColor: atomColor + "55"
192
+ }],
193
+ pointerEvents: "none",
194
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
195
+ style: [styles.absCountText, {
196
+ color: atomColor
197
+ }],
198
+ children: String(atom.changeCount)
199
+ })
200
+ })]
201
+ }, atom.label);
202
+ })]
203
+ });
204
+ }
205
+ const styles = _reactNative.StyleSheet.create({
206
+ container: {
207
+ flex: 1
208
+ },
209
+ atomRowWrapper: {
210
+ position: "relative"
211
+ },
212
+ absCountBadge: {
213
+ position: "absolute",
214
+ top: 4,
215
+ right: 10,
216
+ paddingHorizontal: 5,
217
+ paddingVertical: 1,
218
+ borderRadius: 4,
219
+ borderWidth: 1,
220
+ zIndex: 1
221
+ },
222
+ absCountText: {
223
+ fontSize: 9,
224
+ fontWeight: "700",
225
+ fontFamily: "monospace"
226
+ },
227
+ scrollContent: {
228
+ paddingTop: 8,
229
+ paddingBottom: 20
230
+ },
231
+ sectionHeader: {
232
+ flexDirection: "row",
233
+ alignItems: "center",
234
+ paddingHorizontal: 16,
235
+ paddingVertical: 8,
236
+ gap: 8
237
+ },
238
+ sectionTitle: {
239
+ fontSize: 11,
240
+ fontWeight: "700",
241
+ letterSpacing: 0.5,
242
+ color: _sharedUi.macOSColors.text.muted
243
+ },
244
+ sectionCountBadge: {
245
+ backgroundColor: _sharedUi.buoyColors.primary + "26",
246
+ paddingHorizontal: 8,
247
+ paddingVertical: 2,
248
+ borderRadius: 4
249
+ },
250
+ sectionCountText: {
251
+ fontSize: 10,
252
+ fontWeight: "700",
253
+ color: _sharedUi.buoyColors.primary,
254
+ fontFamily: "monospace"
255
+ },
256
+ emptyState: {
257
+ alignItems: "center",
258
+ paddingVertical: 40
259
+ },
260
+ emptyTitle: {
261
+ color: _sharedUi.macOSColors.text.primary,
262
+ fontSize: 14,
263
+ fontWeight: "600",
264
+ marginTop: 12,
265
+ marginBottom: 6
266
+ },
267
+ emptyText: {
268
+ color: _sharedUi.macOSColors.text.muted,
269
+ fontSize: 12,
270
+ textAlign: "center",
271
+ lineHeight: 18
272
+ }
273
+ });
274
+ const expandedStyles = _reactNative.StyleSheet.create({
275
+ container: {
276
+ gap: 10
277
+ },
278
+ viewHistoryButton: {
279
+ marginLeft: 4
280
+ },
281
+ viewHistoryText: {
282
+ fontSize: 10,
283
+ fontWeight: "600",
284
+ fontFamily: "monospace"
285
+ },
286
+ dataContainer: {
287
+ backgroundColor: _sharedUi.buoyColors.base,
288
+ borderRadius: 6,
289
+ borderWidth: 1,
290
+ borderColor: _sharedUi.buoyColors.border,
291
+ overflow: "hidden",
292
+ minHeight: 60
293
+ },
294
+ primitiveText: {
295
+ color: _sharedUi.buoyColors.text,
296
+ fontSize: 12,
297
+ fontFamily: "monospace",
298
+ padding: 14
299
+ }
300
+ });
@@ -1 +1,113 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.JotaiAtomChangeItem=JotaiAtomChangeItem;var _reactNative=require("react-native"),_sharedUi=require("@buoy-gg/shared-ui"),_jotaiStateStore=require("../utils/jotaiStateStore"),_jsxRuntime=require("react/jsx-runtime");function getStatusLabel(e,t){return"initial"===e?"Initial":t.charAt(0).toUpperCase()+t.slice(1)}function getCategoryColor(e,t){return"initial"===e?_sharedUi.buoyColors.textMuted:_jotaiStateStore.jotaiStateStore.getAtomColor(t)}function formatCompact(e,t=20){if(void 0===e)return"undefined";if(null===e)return"null";if("boolean"==typeof e)return String(e);if("number"==typeof e)return String(e);if("string"==typeof e)return`"${e.length>t?e.slice(0,t-1)+"…":e}"`;if(Array.isArray(e))return 0===e.length?"[]":`[${e.length} item${1===e.length?"":"s"}]`;if("object"==typeof e){const t=Object.keys(e);return 0===t.length?"{}":`{${t.slice(0,2).join(", ")}${t.length>2?"…":""}}`}return String(e).slice(0,t)}function getSublabel(e){return e.hasValueChange?`${formatCompact(e.prevValue)} → ${formatCompact(e.nextValue)}`:"no change"}function getBadgeText(e){return"initial"===e.category?"INIT":"WRITE"}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.valuePreview||"atom()"}function JotaiAtomChangeItem({change:e,onPress:t}){const a=getCategoryColor(e.category,e.atomLabel),r=getStatusLabel(e.category,e.atomLabel),n=getSublabel(e),i=getPrimaryText(e),o=getBadgeText(e),s=e.hasValueChange?(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.badgeContainer,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.badgeText,{color:a}],children:o}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.changeBadge,children:(0,_jsxRuntime.jsx)(_sharedUi.Zap,{size:12,color:_sharedUi.buoyColors.warning})})]}):void 0;return(0,_jsxRuntime.jsx)(_sharedUi.CompactRow,{statusDotColor:a,statusLabel:r,statusSublabel:n,primaryText:i,bottomRightText:(0,_sharedUi.formatRelativeTime)(e.timestamp),customBadge:s,badgeText:s?void 0:o,badgeColor:a,showChevron:!0,onPress:()=>t(e)})}const styles=_reactNative.StyleSheet.create({badgeContainer:{flexDirection:"row",alignItems:"center",gap:4},badgeText:{fontSize:11,fontWeight:"600",fontFamily:"monospace"},changeBadge:{paddingHorizontal:4}});
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.JotaiAtomChangeItem = JotaiAtomChangeItem;
7
+ var _reactNative = require("react-native");
8
+ var _sharedUi = require("@buoy-gg/shared-ui");
9
+ var _jotaiStateStore = require("../utils/jotaiStateStore");
10
+ var _jsxRuntime = require("react/jsx-runtime");
11
+ /**
12
+ * Compact list item for displaying a Jotai atom change
13
+ *
14
+ * Mirrors ZustandStateChangeItem.tsx — uses shared CompactRow for consistent styling
15
+ */
16
+
17
+ function getStatusLabel(category, atomLabel) {
18
+ if (category === "initial") return "Initial";
19
+ return atomLabel.charAt(0).toUpperCase() + atomLabel.slice(1);
20
+ }
21
+ function getCategoryColor(category, atomLabel) {
22
+ if (category === "initial") return _sharedUi.buoyColors.textMuted;
23
+ return _jotaiStateStore.jotaiStateStore.getAtomColor(atomLabel);
24
+ }
25
+ function formatCompact(value, maxLen = 20) {
26
+ if (value === undefined) return "undefined";
27
+ if (value === null) return "null";
28
+ if (typeof value === "boolean") return String(value);
29
+ if (typeof value === "number") return String(value);
30
+ if (typeof value === "string") {
31
+ const truncated = value.length > maxLen ? value.slice(0, maxLen - 1) + "…" : value;
32
+ return `"${truncated}"`;
33
+ }
34
+ if (Array.isArray(value)) {
35
+ return value.length === 0 ? "[]" : `[${value.length} item${value.length === 1 ? "" : "s"}]`;
36
+ }
37
+ if (typeof value === "object") {
38
+ const keys = Object.keys(value);
39
+ if (keys.length === 0) return "{}";
40
+ return `{${keys.slice(0, 2).join(", ")}${keys.length > 2 ? "…" : ""}}`;
41
+ }
42
+ return String(value).slice(0, maxLen);
43
+ }
44
+ function getSublabel(change) {
45
+ if (!change.hasValueChange) return "no change";
46
+ return `${formatCompact(change.prevValue)} → ${formatCompact(change.nextValue)}`;
47
+ }
48
+ function getBadgeText(change) {
49
+ if (change.category === "initial") return "INIT";
50
+ return "WRITE";
51
+ }
52
+ function getPrimaryText(change) {
53
+ if (change.changedKeys.length > 0 && change.changedKeys.length <= 3) {
54
+ return change.changedKeys.join(", ");
55
+ }
56
+ if (change.changedKeys.length > 3) {
57
+ return `${change.changedKeys.slice(0, 2).join(", ")} +${change.changedKeys.length - 2}`;
58
+ }
59
+ return change.valuePreview || "atom()";
60
+ }
61
+ function JotaiAtomChangeItem({
62
+ change,
63
+ onPress
64
+ }) {
65
+ const statusColor = getCategoryColor(change.category, change.atomLabel);
66
+ const statusLabel = getStatusLabel(change.category, change.atomLabel);
67
+ const sublabel = getSublabel(change);
68
+ const primaryText = getPrimaryText(change);
69
+ const badgeText = getBadgeText(change);
70
+ const relativeTime = (0, _sharedUi.useRelativeTime)(change.timestamp);
71
+ const customBadge = change.hasValueChange ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
72
+ style: styles.badgeContainer,
73
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
74
+ style: [styles.badgeText, {
75
+ color: statusColor
76
+ }],
77
+ children: badgeText
78
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
79
+ style: styles.changeBadge,
80
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Zap, {
81
+ size: 12,
82
+ color: _sharedUi.buoyColors.warning
83
+ })
84
+ })]
85
+ }) : undefined;
86
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.CompactRow, {
87
+ statusDotColor: statusColor,
88
+ statusLabel: statusLabel,
89
+ statusSublabel: sublabel,
90
+ primaryText: primaryText,
91
+ bottomRightText: relativeTime,
92
+ customBadge: customBadge,
93
+ badgeText: customBadge ? undefined : badgeText,
94
+ badgeColor: statusColor,
95
+ showChevron: true,
96
+ onPress: () => onPress(change)
97
+ });
98
+ }
99
+ const styles = _reactNative.StyleSheet.create({
100
+ badgeContainer: {
101
+ flexDirection: "row",
102
+ alignItems: "center",
103
+ gap: 4
104
+ },
105
+ badgeText: {
106
+ fontSize: 11,
107
+ fontWeight: "600",
108
+ fontFamily: "monospace"
109
+ },
110
+ changeBadge: {
111
+ paddingHorizontal: 4
112
+ }
113
+ });