@buoy-gg/jotai 2.1.10

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 (45) hide show
  1. package/LICENSE +58 -0
  2. package/lib/commonjs/index.js +1 -0
  3. package/lib/commonjs/jotai/components/JotaiAtomBrowser.js +1 -0
  4. package/lib/commonjs/jotai/components/JotaiAtomChangeItem.js +1 -0
  5. package/lib/commonjs/jotai/components/JotaiAtomDetailContent.js +1 -0
  6. package/lib/commonjs/jotai/components/JotaiEventFilterView.js +1 -0
  7. package/lib/commonjs/jotai/components/JotaiIcon.js +1 -0
  8. package/lib/commonjs/jotai/components/JotaiModal.js +1 -0
  9. package/lib/commonjs/jotai/components/index.js +1 -0
  10. package/lib/commonjs/jotai/hooks/useJotaiAtomChanges.js +1 -0
  11. package/lib/commonjs/jotai/index.js +1 -0
  12. package/lib/commonjs/jotai/types/index.js +1 -0
  13. package/lib/commonjs/jotai/utils/jotaiStateStore.js +1 -0
  14. package/lib/commonjs/jotai/utils/watchAtoms.js +1 -0
  15. package/lib/commonjs/package.json +1 -0
  16. package/lib/commonjs/preset.js +1 -0
  17. package/lib/module/index.js +1 -0
  18. package/lib/module/jotai/components/JotaiAtomBrowser.js +1 -0
  19. package/lib/module/jotai/components/JotaiAtomChangeItem.js +1 -0
  20. package/lib/module/jotai/components/JotaiAtomDetailContent.js +1 -0
  21. package/lib/module/jotai/components/JotaiEventFilterView.js +1 -0
  22. package/lib/module/jotai/components/JotaiIcon.js +1 -0
  23. package/lib/module/jotai/components/JotaiModal.js +1 -0
  24. package/lib/module/jotai/components/index.js +1 -0
  25. package/lib/module/jotai/hooks/useJotaiAtomChanges.js +1 -0
  26. package/lib/module/jotai/index.js +1 -0
  27. package/lib/module/jotai/types/index.js +1 -0
  28. package/lib/module/jotai/utils/jotaiStateStore.js +1 -0
  29. package/lib/module/jotai/utils/watchAtoms.js +1 -0
  30. package/lib/module/preset.js +1 -0
  31. package/lib/typescript/index.d.ts +46 -0
  32. package/lib/typescript/jotai/components/JotaiAtomBrowser.d.ts +15 -0
  33. package/lib/typescript/jotai/components/JotaiAtomChangeItem.d.ts +13 -0
  34. package/lib/typescript/jotai/components/JotaiAtomDetailContent.d.ts +28 -0
  35. package/lib/typescript/jotai/components/JotaiEventFilterView.d.ts +16 -0
  36. package/lib/typescript/jotai/components/JotaiIcon.d.ts +10 -0
  37. package/lib/typescript/jotai/components/JotaiModal.d.ts +10 -0
  38. package/lib/typescript/jotai/components/index.d.ts +7 -0
  39. package/lib/typescript/jotai/hooks/useJotaiAtomChanges.d.ts +37 -0
  40. package/lib/typescript/jotai/index.d.ts +11 -0
  41. package/lib/typescript/jotai/types/index.d.ts +59 -0
  42. package/lib/typescript/jotai/utils/jotaiStateStore.d.ts +47 -0
  43. package/lib/typescript/jotai/utils/watchAtoms.d.ts +62 -0
  44. package/lib/typescript/preset.d.ts +92 -0
  45. package/package.json +81 -0
package/LICENSE ADDED
@@ -0,0 +1,58 @@
1
+ PROPRIETARY SOFTWARE LICENSE
2
+
3
+ Copyright (c) 2024-present Buoy. All rights reserved.
4
+
5
+ This software and its source code are proprietary and confidential.
6
+
7
+ NOTICE: This is NOT open source software. This software is licensed,
8
+ not sold, and is protected by copyright laws and international treaties.
9
+
10
+ TERMS AND CONDITIONS:
11
+
12
+ 1. LICENSE GRANT
13
+ Subject to the terms of this Agreement and payment of applicable fees,
14
+ Buoy grants you a limited, non-exclusive, non-transferable license
15
+ to use the compiled software packages in your applications.
16
+
17
+ 2. RESTRICTIONS
18
+ You may NOT:
19
+ - Copy, modify, or distribute the source code
20
+ - Reverse engineer, decompile, or disassemble the software
21
+ - Remove or alter any proprietary notices or labels
22
+ - Sublicense, rent, lease, or lend the software
23
+ - Use the software to create competing products
24
+ - Share access credentials with unauthorized parties
25
+
26
+ 3. OWNERSHIP
27
+ React Buoy retains all right, title, and interest in the software,
28
+ including all intellectual property rights. This license does not
29
+ grant you any rights to trademarks or service marks.
30
+
31
+ 4. TERMINATION
32
+ This license is effective until terminated. Your rights under this
33
+ license will terminate automatically without notice if you fail to
34
+ comply with any of its terms. Upon termination, you must cease all
35
+ use and destroy all copies of the software.
36
+
37
+ 5. DISCLAIMER OF WARRANTIES
38
+ THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
39
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
40
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT.
41
+
42
+ 6. LIMITATION OF LIABILITY
43
+ IN NO EVENT SHALL BUOY BE LIABLE FOR ANY INDIRECT, INCIDENTAL,
44
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN
45
+ CONNECTION WITH THIS LICENSE OR THE USE OF THE SOFTWARE.
46
+
47
+ 7. GOVERNING LAW
48
+ This Agreement shall be governed by and construed in accordance with
49
+ the laws of the United States, without regard to its conflict of
50
+ law provisions.
51
+
52
+ For licensing inquiries and subscription information:
53
+ - Website: https://buoy.gg
54
+ - Email: AustinLovesWorking@gmail.com
55
+
56
+ Unauthorized reproduction or distribution of this software, or any
57
+ portion of it, may result in severe civil and criminal penalties,
58
+ and will be prosecuted to the maximum extent possible under the law.
@@ -0,0 +1 @@
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");
@@ -0,0 +1 @@
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}});
@@ -0,0 +1 @@
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}});
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.JotaiAtomDetailContent=JotaiAtomDetailContent,exports.JotaiAtomDetailFooter=JotaiAtomDetailFooter;var _react=_interopRequireWildcard(require("react")),_reactNative=require("react-native"),_sharedUi=require("@buoy-gg/shared-ui"),_dataViewer=require("@buoy-gg/shared-ui/dataViewer"),_license=require("@buoy-gg/license"),_jotaiStateStore=require("../utils/jotaiStateStore"),_jsxRuntime=require("react/jsx-runtime");function _interopRequireWildcard(e,t){if("function"==typeof WeakMap)var a=new WeakMap,i=new WeakMap;return(_interopRequireWildcard=function(e,t){if(!t&&e&&e.__esModule)return e;var o,r,n={__proto__:null,default:e};if(null===e||"object"!=typeof e&&"function"!=typeof e)return n;if(o=t?i:a){if(o.has(e))return o.get(e);o.set(e,n)}for(const t in e)"default"!==t&&{}.hasOwnProperty.call(e,t)&&((r=(o=Object.defineProperty)&&Object.getOwnPropertyDescriptor(e,t))&&(r.get||r.set)?o(n,t,r):n[t]=e[t]);return n})(e,t)}const VIEW_CONFIGS=[{key:"change",label:"CHANGE",icon:_sharedUi.FileText,activeColor:_sharedUi.macOSColors.semantic.warning},{key:"value",label:"VALUE",icon:_sharedUi.Database,activeColor:_sharedUi.macOSColors.semantic.info},{key:"diff",label:"DIFF",icon:_sharedUi.GitBranch,activeColor:_sharedUi.macOSColors.semantic.success}];function DetailViewToggle({activeView:e,onViewChange:t,diffDisabled:a}){return(0,_jsxRuntime.jsx)(_reactNative.View,{style:toggleStyles.container,children:VIEW_CONFIGS.map(i=>{const o=e===i.key,r="diff"===i.key&&a,n=i.icon;return(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:[toggleStyles.card,o&&[toggleStyles.cardActive,{borderColor:i.activeColor}],r&&toggleStyles.cardDisabled],onPress:()=>!r&&t(i.key),activeOpacity:.7,children:(0,_jsxRuntime.jsxs)(_reactNative.View,{style:toggleStyles.cardContent,children:[(0,_jsxRuntime.jsx)(n,{size:14,color:o?i.activeColor:r?_sharedUi.macOSColors.text.muted:_sharedUi.macOSColors.text.secondary}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[toggleStyles.cardLabel,o&&{color:i.activeColor},r&&{color:_sharedUi.macOSColors.text.muted}],children:i.label})]})},i.key)})})}function getCategoryInfo(e){return"initial"===e?{label:"INITIAL",color:_sharedUi.buoyColors.textMuted,bgColor:_sharedUi.buoyColors.textMuted+"26"}:{label:"WRITE",color:_sharedUi.buoyColors.success,bgColor:_sharedUi.buoyColors.success+"26"}}function formatTime(e){const t=new Date(e);return`${t.getHours().toString().padStart(2,"0")}:${t.getMinutes().toString().padStart(2,"0")}:${t.getSeconds().toString().padStart(2,"0")}.${t.getMilliseconds().toString().padStart(3,"0")}`}function formatTimestamp(e){return new Date(e).toLocaleTimeString("en-US",{hour12:!1,hour:"2-digit",minute:"2-digit",second:"2-digit"})}function getValueType(e){return null===e?"null":void 0===e?"undefined":Array.isArray(e)?"array":typeof e}function getChangeLabel(e){return"initial"===e?"INIT":"WRITE"}const DIFF_MODE_TABS=[{key:"tree",label:"TREE VIEW"},{key:"split",label:"SPLIT VIEW"}],JotaiAtomInfoView=(0,_react.memo)(function({change:e}){const t=(0,_license.useIsPro)(),[a,i]=(0,_react.useState)(!1),o=getCategoryInfo(e.category),r=_jotaiStateStore.jotaiStateStore.getAtomColor(e.atomLabel),n=(0,_react.useCallback)(async()=>{t?await(0,_sharedUi.copyToClipboard)(e.nextValue):i(!0)},[e.nextValue,t]);return(0,_jsxRuntime.jsxs)(_reactNative.ScrollView,{style:infoStyles.container,contentContainerStyle:infoStyles.content,showsVerticalScrollIndicator:!1,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:infoStyles.card,children:[(0,_jsxRuntime.jsx)(_reactNative.View,{style:infoStyles.sectionHeader,children:(0,_jsxRuntime.jsxs)(_reactNative.View,{style:infoStyles.sectionHeaderLeft,children:[(0,_jsxRuntime.jsx)(_sharedUi.Info,{size:14,color:_sharedUi.buoyColors.primary}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:infoStyles.sectionTitle,children:"CHANGE INFO"})]})}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:infoStyles.cardContent,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:infoStyles.infoRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:infoStyles.infoLabel,children:"Atom"}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[infoStyles.infoValue,infoStyles.infoValueMono,{color:r}],numberOfLines:1,ellipsizeMode:"middle",children:e.atomLabel})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:infoStyles.infoRow,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:infoStyles.infoLabel,children:"Time"}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[infoStyles.infoValue,infoStyles.infoValueMono],children:formatTime(e.timestamp)})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:infoStyles.badgeRow,children:[(0,_jsxRuntime.jsx)(_reactNative.View,{style:[infoStyles.categoryBadge,{backgroundColor:o.bgColor}],children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[infoStyles.categoryText,{color:o.color}],children:o.label})}),e.hasValueChange?(0,_jsxRuntime.jsxs)(_reactNative.View,{style:infoStyles.changesBadge,children:[(0,_jsxRuntime.jsx)(_sharedUi.Zap,{size:10,color:_sharedUi.buoyColors.success}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:infoStyles.changesText,children:e.diffSummary||"changed"})]}):(0,_jsxRuntime.jsx)(_reactNative.View,{style:infoStyles.noChangesBadge,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:infoStyles.noChangesText,children:"no change"})})]})]})]}),e.changedKeys.length>0&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:infoStyles.card,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:infoStyles.sectionHeader,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:infoStyles.sectionHeaderLeft,children:[(0,_jsxRuntime.jsx)(_sharedUi.Zap,{size:14,color:_sharedUi.buoyColors.primary}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:infoStyles.sectionTitle,children:"CHANGED KEYS"})]}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:infoStyles.countBadge,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:infoStyles.countText,children:e.changedKeys.length})})]}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:infoStyles.cardContent,children:(0,_jsxRuntime.jsx)(_reactNative.View,{style:infoStyles.keysContainer,children:e.changedKeys.map(e=>(0,_jsxRuntime.jsx)(_reactNative.View,{style:infoStyles.keyBadge,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:infoStyles.keyText,children:e})},e))})})]}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:infoStyles.actionsRow,children:(0,_jsxRuntime.jsx)(_reactNative.View,{style:[infoStyles.actionButton,infoStyles.actionButtonCopy],onTouchEnd:n,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[infoStyles.actionButtonText,{color:_sharedUi.buoyColors.primary}],children:"COPY VALUE"})})}),(0,_jsxRuntime.jsx)(_sharedUi.ProUpgradeModal,{visible:a,onClose:()=>i(!1),featureName:"Copy"})]})});function JotaiAtomDetailContent({change:e,changes:t,selectedIndex:a,onIndexChange:i,disableInternalFooter:o=!1}){const[r,n]=(0,_react.useState)("change"),[s,l]=(0,_react.useState)("tree"),c=t.length,d=_jotaiStateStore.jotaiStateStore.getAtomColor(e.atomLabel),u=getChangeLabel(e.category),m=getValueType(e.nextValue),y=c-a,x=a<c-1?a+1:null,_=null!==x?t[x]:null,g=y-1,h=(0,_react.useMemo)(()=>({index:x??0,label:g>0?`#${g}`:"Initial",timestamp:_?formatTimestamp(_.timestamp):"",relativeTime:_?(0,_sharedUi.formatRelativeTime)(new Date(_.timestamp)):"value",badge:_?(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.changeBadgeSmall,{backgroundColor:`${_jotaiStateStore.jotaiStateStore.getAtomColor(_.atomLabel)}20`}],children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.changeTextSmall,{color:_jotaiStateStore.jotaiStateStore.getAtomColor(_.atomLabel)}],children:getChangeLabel(_.category)})}):void 0}),[x,_,g]),f=(0,_react.useMemo)(()=>({index:a,label:`#${y}`,timestamp:formatTimestamp(e.timestamp),relativeTime:(0,_sharedUi.formatRelativeTime)(new Date(e.timestamp)),badge:(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.changeBadgeSmall,{backgroundColor:`${d}20`}],children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.changeTextSmall,{color:d}],children:u})})}),[a,e.timestamp,d,u,y]),j=(0,_react.useCallback)(()=>{const t=(0,_sharedUi.parseValue)(e.nextValue);return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.contentCard,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.valueHeader,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.valueLabel,children:"VALUE AFTER CHANGE"}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.valueHeaderBadges,children:[(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.changeBadge,{backgroundColor:`${d}20`}],children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.changeText,{color:d}],children:u})}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.typeBadge,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.typeText,children:m.toUpperCase()})})]})]}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.valueBox,children:"object"!==m&&"array"!==m||!t?(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.valueText,children:null===t?"null":void 0===t?"undefined":"string"===m?`"${t}"`:String(t)}):(0,_jsxRuntime.jsx)(_dataViewer.DataViewer,{title:"",data:t,showTypeFilter:!1})})]})},[e.nextValue,d,u,m]),p=(0,_react.useCallback)(()=>{const t=(0,_sharedUi.parseValue)(e.prevValue),a=(0,_sharedUi.parseValue)(e.nextValue);return"split"===s?(0,_jsxRuntime.jsx)(_reactNative.ScrollView,{style:{flex:1},showsVerticalScrollIndicator:!0,children:(0,_jsxRuntime.jsx)(_dataViewer.SplitDiffViewer,{oldValue:t,newValue:a,theme:_dataViewer.diffThemes.devToolsDefault,options:{hideLineNumbers:!1,disableWordDiff:!1,showDiffOnly:!1,compareMethod:"words",contextLines:3},showThemeName:!1})}):(0,_jsxRuntime.jsx)(_dataViewer.TreeDiffViewer,{oldValue:t,newValue:a})},[e.prevValue,e.nextValue,s]),b=(0,_react.useCallback)(()=>{i(Math.min(c-1,a+1))},[a,c,i]),S=(0,_react.useCallback)(()=>{i(Math.max(0,a-1))},[a,i]),C=c<=1;return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.container,children:[(0,_jsxRuntime.jsx)(DetailViewToggle,{activeView:r,onViewChange:n,diffDisabled:C}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.contentArea,children:["change"===r&&(0,_jsxRuntime.jsx)(JotaiAtomInfoView,{change:e}),"value"===r&&(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.stateContainer,children:j()}),"diff"===r&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.diffContainer,children:[(0,_jsxRuntime.jsx)(_sharedUi.DiffModeTabs,{tabs:DIFF_MODE_TABS,activeTab:s,onTabChange:l}),(0,_jsxRuntime.jsx)(_sharedUi.CompareBar,{leftEvent:h,rightEvent:f}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.diffContent,children:p()})]})]}),!o&&c>1&&(0,_jsxRuntime.jsx)(_sharedUi.EventStepperFooter,{currentIndex:y-1,totalItems:c,onPrevious:b,onNext:S,itemLabel:"Change",subtitle:(0,_sharedUi.formatRelativeTime)(new Date(e.timestamp)),absolute:!0})]})}function JotaiAtomDetailFooter({change:e,changes:t,selectedIndex:a,onIndexChange:i}){const o=t.length;if(o<=1)return null;const r=o-a;return(0,_jsxRuntime.jsx)(_sharedUi.EventStepperFooter,{currentIndex:r-1,totalItems:o,onPrevious:()=>i(Math.min(o-1,a+1)),onNext:()=>i(Math.max(0,a-1)),itemLabel:"Change",subtitle:(0,_sharedUi.formatRelativeTime)(new Date(e.timestamp))})}const styles=_reactNative.StyleSheet.create({container:{flex:1,backgroundColor:_sharedUi.macOSColors.background.base},contentArea:{flex:1,paddingBottom:96},stateContainer:{flex:1,padding:14},contentCard:{backgroundColor:_sharedUi.macOSColors.background.card,borderRadius:14,padding:14,borderWidth:1,borderColor:_sharedUi.macOSColors.border.default},valueHeader:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",marginBottom:8},valueLabel:{fontSize:10,color:_sharedUi.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:_sharedUi.macOSColors.background.input},typeText:{fontSize:9,fontWeight:"600",color:_sharedUi.macOSColors.text.muted,fontFamily:"monospace"},valueBox:{backgroundColor:_sharedUi.macOSColors.background.base,borderRadius:6,borderWidth:1,borderColor:_sharedUi.macOSColors.border.input,padding:8},valueText:{fontSize:12,color:_sharedUi.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"}}),toggleStyles=_reactNative.StyleSheet.create({container:{flexDirection:"row",gap:8,padding:14,backgroundColor:_sharedUi.macOSColors.background.base},card:{flex:1,backgroundColor:_sharedUi.macOSColors.background.card,borderRadius:12,borderWidth:1,borderColor:_sharedUi.macOSColors.border.default,paddingVertical:10,paddingHorizontal:10,justifyContent:"center"},cardActive:{borderWidth:1.5,backgroundColor:"rgba(0, 184, 230, 0.05)"},cardDisabled:{opacity:.5},cardContent:{flexDirection:"row",alignItems:"center",gap:6},cardLabel:{fontSize:10,fontWeight:"700",letterSpacing:.5,color:_sharedUi.macOSColors.text.secondary}}),infoStyles=_reactNative.StyleSheet.create({container:{flex:1},content:{padding:8,paddingBottom:100,gap:16},card:{backgroundColor:_sharedUi.buoyColors.card,borderRadius:6,borderWidth:1,borderColor:_sharedUi.buoyColors.primary+"4D",overflow:"hidden",shadowColor:_sharedUi.buoyColors.primary,shadowOffset:{width:0,height:0},shadowOpacity:.1,shadowRadius:6},sectionHeader:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",paddingHorizontal:12,paddingVertical:10,borderBottomWidth:1,borderBottomColor:_sharedUi.buoyColors.primary+"33",backgroundColor:_sharedUi.buoyColors.primary+"15"},sectionHeaderLeft:{flexDirection:"row",alignItems:"center",gap:6},sectionTitle:{fontSize:12,fontWeight:"600",letterSpacing:.5,color:_sharedUi.buoyColors.primary,fontFamily:"monospace"},cardContent:{padding:14,gap:10},infoRow:{flexDirection:"row",alignItems:"center",justifyContent:"space-between"},infoLabel:{fontSize:11,color:_sharedUi.buoyColors.textMuted,fontWeight:"500"},infoValue:{fontSize:11,color:_sharedUi.buoyColors.text,fontWeight:"500",flex:1,textAlign:"right",marginLeft:12},infoValueMono:{fontFamily:"monospace"},badgeRow:{flexDirection:"row",flexWrap:"wrap",gap:8,marginTop:6},categoryBadge:{paddingHorizontal:8,paddingVertical:3,borderRadius:4},categoryText:{fontSize:9,fontWeight:"700",letterSpacing:.3},changesBadge:{flexDirection:"row",alignItems:"center",gap:4,paddingHorizontal:8,paddingVertical:3,borderRadius:4,backgroundColor:_sharedUi.buoyColors.success+"26"},changesText:{fontSize:9,fontWeight:"600",color:_sharedUi.buoyColors.success},noChangesBadge:{paddingHorizontal:8,paddingVertical:3,borderRadius:4,backgroundColor:_sharedUi.buoyColors.input},noChangesText:{fontSize:9,fontWeight:"600",color:_sharedUi.buoyColors.textMuted},keysContainer:{flexDirection:"row",flexWrap:"wrap",gap:6},keyBadge:{paddingHorizontal:8,paddingVertical:4,borderRadius:4,backgroundColor:_sharedUi.buoyColors.primary+"20",borderWidth:1,borderColor:_sharedUi.buoyColors.primary+"40"},keyText:{fontSize:11,fontWeight:"600",color:_sharedUi.buoyColors.primary,fontFamily:"monospace"},countBadge:{paddingHorizontal:8,paddingVertical:3,borderRadius:4,backgroundColor:_sharedUi.buoyColors.primary+"26"},countText:{fontSize:9,fontWeight:"700",color:_sharedUi.buoyColors.primary,fontFamily:"monospace"},actionsRow:{flexDirection:"row",gap:12},actionButton:{paddingHorizontal:14,paddingVertical:8,borderRadius:8,borderWidth:1},actionButtonCopy:{borderColor:_sharedUi.buoyColors.primary+"40",backgroundColor:_sharedUi.buoyColors.primary+"15"},actionButtonText:{fontSize:10,fontWeight:"700",fontFamily:"monospace",letterSpacing:.3}});
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.JotaiEventFilterView=JotaiEventFilterView;var _react=require("react"),_reactNative=require("react-native"),_sharedUi=require("@buoy-gg/shared-ui"),_jotaiStateStore=require("../utils/jotaiStateStore"),_jsxRuntime=require("react/jsx-runtime");function getAtomColorForPattern(e,t){const o=t.find(t=>t.label.toLowerCase().includes(e.toLowerCase()));return o?o.color:null}function JotaiEventFilterView({ignoredPatterns:e,onTogglePattern:t,onAddPattern:o,atoms:r}){const[i,a]=(0,_react.useState)("");return(0,_jsxRuntime.jsxs)(_reactNative.ScrollView,{style:styles.container,contentContainerStyle:styles.scrollContent,showsVerticalScrollIndicator:!1,nestedScrollEnabled:!0,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.section,children:[(0,_jsxRuntime.jsxs)(_sharedUi.SectionHeader,{children:[(0,_jsxRuntime.jsx)(_sharedUi.SectionHeader.Icon,{icon:_sharedUi.Filter,color:_sharedUi.buoyColors.textSecondary,size:12}),(0,_jsxRuntime.jsx)(_sharedUi.SectionHeader.Title,{children:"REGISTERED ATOMS"})]}),0===r.length?(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.emptyText,children:"No atoms registered yet."}):(0,_jsxRuntime.jsx)(_reactNative.ScrollView,{style:styles.atomList,contentContainerStyle:styles.atomListContent,nestedScrollEnabled:!0,children:r.map(o=>{const r=_jotaiStateStore.jotaiStateStore.getAtomColor(o.label),i=Array.from(e).some(e=>o.label.toLowerCase().includes(e.toLowerCase()));return(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{style:[styles.atomRow,i&&styles.atomRowFiltered],onPress:()=>t(o.label),activeOpacity:.7,children:[(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.atomDot,{backgroundColor:r}]}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.atomRowText,{color:r},i&&styles.atomRowTextFiltered],numberOfLines:1,children:o.label}),i?(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.filteredLabel,children:"filtered"}):(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.addLabel,{color:r}],children:"+ add"})]},o.label)})}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.addInputWrapper,children:(0,_jsxRuntime.jsx)(_reactNative.TextInput,{value:i,onChangeText:a,onSubmitEditing:()=>{const t=i.trim();t&&!e.has(t)&&(o(t),a(""))},placeholder:"Type a pattern and press Enter...",placeholderTextColor:_sharedUi.macOSColors.text.muted,returnKeyType:"done",autoCapitalize:"none",autoCorrect:!1,style:styles.patternInput})})]}),e.size>0&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.section,children:[(0,_jsxRuntime.jsxs)(_sharedUi.SectionHeader,{children:[(0,_jsxRuntime.jsx)(_sharedUi.SectionHeader.Icon,{icon:_sharedUi.Filter,color:_sharedUi.buoyColors.textSecondary,size:12}),(0,_jsxRuntime.jsx)(_sharedUi.SectionHeader.Title,{children:"ACTIVE FILTERS"})]}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.patternList,children:Array.from(e).map(e=>{const o=getAtomColorForPattern(e,r);return(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{style:styles.patternRow,onPress:()=>t(e),activeOpacity:.8,children:[o?(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.atomDot,{backgroundColor:o}]}):null,(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.patternText,o?{color:o}:null],numberOfLines:1,children:e}),(0,_jsxRuntime.jsx)(_sharedUi.X,{size:12,color:_sharedUi.buoyColors.primary+"80"})]},e)})})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.section,children:[(0,_jsxRuntime.jsxs)(_sharedUi.SectionHeader,{children:[(0,_jsxRuntime.jsx)(_sharedUi.SectionHeader.Icon,{icon:_sharedUi.Filter,color:_sharedUi.buoyColors.textSecondary,size:12}),(0,_jsxRuntime.jsx)(_sharedUi.SectionHeader.Title,{children:"HOW ATOM FILTERS WORK"})]}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.howItWorksText,children:"Patterns hide matching atoms from both the Atoms tab and the Events tab. Tap an atom above to quickly add it as a filter."}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.examplesContainer,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.examplesTitle,children:"EXAMPLES:"}),["• count -> hides countAtom from atoms & events","• auth -> hides authAtom, authStatusAtom","• user -> hides userAtom from both tabs"].map(e=>(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.exampleItem,children:e},e))]})]})]})}const styles=_reactNative.StyleSheet.create({container:{flex:1,backgroundColor:_sharedUi.buoyColors.base},scrollContent:{paddingTop:16,paddingHorizontal:16,paddingBottom:24,gap:16},section:{backgroundColor:_sharedUi.buoyColors.card,borderRadius:16,borderWidth:1,borderColor:_sharedUi.buoyColors.border,overflow:"hidden"},atomList:{maxHeight:180},atomListContent:{paddingHorizontal:16,paddingTop:8,paddingBottom:16,gap:10},atomRow:{flexDirection:"row",alignItems:"center",gap:10,paddingVertical:10,paddingHorizontal:12,backgroundColor:_sharedUi.buoyColors.hover,borderRadius:8,borderWidth:1,borderColor:_sharedUi.buoyColors.border},atomRowFiltered:{opacity:.45},atomDot:{width:7,height:7,borderRadius:3.5},atomRowText:{flex:1,fontSize:12,fontWeight:"600",fontFamily:"monospace"},atomRowTextFiltered:{color:_sharedUi.macOSColors.text.muted,textDecorationLine:"line-through"},filteredLabel:{fontSize:10,fontWeight:"500",color:_sharedUi.macOSColors.text.disabled,fontFamily:"monospace"},addLabel:{fontSize:10,fontWeight:"600",fontFamily:"monospace"},addInputWrapper:{paddingHorizontal:16,paddingTop:8,paddingBottom:8},patternList:{paddingHorizontal:16,paddingBottom:16,gap:8},patternRow:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",paddingVertical:10,paddingHorizontal:12,backgroundColor:_sharedUi.buoyColors.hover,borderRadius:8,borderWidth:1,borderColor:_sharedUi.buoyColors.border,gap:8},patternText:{flex:1,fontSize:12,fontFamily:"monospace",color:_sharedUi.buoyColors.text},howItWorksText:{fontSize:11,color:_sharedUi.buoyColors.textSecondary,lineHeight:16,marginTop:8,paddingHorizontal:16,fontFamily:"monospace"},examplesContainer:{paddingTop:8,paddingHorizontal:16,paddingBottom:16,borderTopWidth:1,borderTopColor:_sharedUi.buoyColors.border,marginTop:12},examplesTitle:{fontSize:10,fontWeight:"600",color:_sharedUi.buoyColors.textMuted,fontFamily:"monospace",letterSpacing:.5,marginBottom:6},exampleItem:{fontSize:10,color:_sharedUi.buoyColors.textMuted,fontFamily:"monospace",lineHeight:16},emptyText:{fontSize:11,color:_sharedUi.macOSColors.text.muted,paddingHorizontal:16,paddingVertical:12,fontFamily:"monospace"},patternInput:{borderWidth:1,borderColor:_sharedUi.buoyColors.primary+"40",borderRadius:8,paddingHorizontal:12,paddingVertical:8,fontSize:12,color:_sharedUi.buoyColors.text,fontFamily:"monospace",backgroundColor:_sharedUi.buoyColors.input}});
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.JOTAI_ICON_COLOR=void 0,exports.JotaiIcon=JotaiIcon;var _reactNative=require("react-native"),_jsxRuntime=require("react/jsx-runtime");const JOTAI_ICON_COLOR=exports.JOTAI_ICON_COLOR="#6C47FF";function JotaiIcon({size:e,color:t}){return(0,_jsxRuntime.jsx)(_reactNative.View,{style:{width:e,height:e,justifyContent:"center",alignItems:"center"},children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:{fontSize:.75*e,color:t||JOTAI_ICON_COLOR,fontWeight:"700"},children:"J"})})}
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.JotaiModal=JotaiModal;var _react=require("react"),_reactNative=require("react-native"),_sharedUi=require("@buoy-gg/shared-ui"),_license=require("@buoy-gg/license"),_useJotaiAtomChanges=require("../hooks/useJotaiAtomChanges"),_JotaiAtomChangeItem=require("./JotaiAtomChangeItem"),_JotaiAtomDetailContent=require("./JotaiAtomDetailContent"),_JotaiAtomBrowser=require("./JotaiAtomBrowser"),_JotaiEventFilterView=require("./JotaiEventFilterView"),_jsxRuntime=require("react/jsx-runtime");const FREE_TIER_CHANGE_LIMIT=25;function EventsEmptyState({isEnabled:e}){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 atom changes"}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.emptyText,children:e?"Atom changes will appear here as values update.":"Enable capture to start recording atom changes"})]})}function JotaiModal({visible:e,onClose:t,onBack:a,onMinimize:r,enableSharedModalDimensions:s=!1}){const o=(0,_license.useIsPro)(),[i,n]=(0,_react.useState)(!1),[l,d]=(0,_react.useState)("atoms"),[c,u]=(0,_react.useState)(null),[m,h]=(0,_react.useState)(!1),[_,x]=(0,_react.useState)(new Set),{filteredChanges:g,filter:j,setFilter:y,atoms:C,clearChanges:b,isEnabled:p,toggleCapture:R}=(0,_useJotaiAtomChanges.useJotaiAtomChanges)(),S=(0,_react.useMemo)(()=>0===_.size?g:g.filter(e=>!Array.from(_).some(t=>e.atomLabel.toLowerCase().includes(t.toLowerCase()))),[g,_]),U=(0,_react.useMemo)(()=>0===_.size?C:C.filter(e=>!Array.from(_).some(t=>e.label.toLowerCase().includes(t.toLowerCase()))),[C,_]),v=(0,_react.useMemo)(()=>o?S:S.slice(0,FREE_TIER_CHANGE_LIMIT),[S,o]),T=(0,_react.useMemo)(()=>o?0:Math.max(0,S.length-FREE_TIER_CHANGE_LIMIT),[S.length,o]),f=T>0,w=(0,_react.useMemo)(()=>c?v.filter(e=>e.atomLabel===c):v,[v,c]),[A,k]=(0,_react.useState)(null),B=(0,_react.useMemo)(()=>{if(null===A)return null;const e=w.findIndex(e=>e.id===A);return e>=0?e:null},[A,w]),M=null!==B?w[B]:null,[N,E]=(0,_react.useState)(""),[I,V]=(0,_react.useState)(!1),J=(0,_react.useRef)(null),O=(0,_react.useRef)(null),H=(0,_react.useCallback)(e=>{},[]),z=e=>{E(e),"events"===l&&y(t=>({...t,searchText:e}))},P=(0,_react.useCallback)(e=>{k(e.id)},[]),L=(0,_react.useCallback)(()=>{n(!0)},[]),F=(0,_react.useCallback)(()=>{k(null)},[]),D=(0,_react.useCallback)(e=>{const t=w[e];t&&k(t.id)},[w]),q=(0,_react.useCallback)(e=>{u(e),k(null)},[]),K=(0,_react.useCallback)(()=>{u(null),k(null)},[]),W=(0,_react.useCallback)(()=>U.reduce((e,t)=>{try{const a=t.getValue();e[t.label]=(0,_sharedUi.truncatePayload)(a)}catch{e[t.label]=null}return e},{}),[U]),G=(0,_react.useCallback)(()=>S.map(e=>({id:e.id,atomLabel:e.atomLabel,timestamp:e.timestamp,prevValue:(0,_sharedUi.truncatePayload)(e.prevValue),nextValue:(0,_sharedUi.truncatePayload)(e.nextValue),hasValueChange:e.hasValueChange,changedKeys:e.changedKeys})),[S]),$=(0,_react.useCallback)(()=>w.map(e=>({id:e.id,atomLabel:e.atomLabel,timestamp:e.timestamp,prevValue:(0,_sharedUi.truncatePayload)(e.prevValue),nextValue:(0,_sharedUi.truncatePayload)(e.nextValue),hasValueChange:e.hasValueChange,changedKeys:e.changedKeys})),[w]),Q=(0,_react.useCallback)(e=>{x(t=>{const a=new Set(t);return a.has(e)?a.delete(e):a.add(e),a})},[]),X=(0,_react.useCallback)(e=>{x(t=>new Set([...t,e]))},[]),Y=(0,_react.useCallback)(e=>{d(e),u(null),k(null),h(!1),N&&(E(""),y(e=>({...e,searchText:""}))),V(!1)},[N,y]),Z=(0,_react.useCallback)(e=>e.id,[]),ee=(0,_react.useCallback)(({item:e})=>(0,_jsxRuntime.jsx)(_JotaiAtomChangeItem.JotaiAtomChangeItem,{change:e,onPress:P}),[P]),te=_.size>0,ae=s?_sharedUi.devToolsStorageKeys.modal.root():"buoy-jotai-modal";if(!e)return null;const re=M&&null!==B?(0,_jsxRuntime.jsx)(_JotaiAtomDetailContent.JotaiAtomDetailFooter,{change:M,changes:w,selectedIndex:B,onIndexChange:D}):null,se=M&&w.length>1?68:0;return(0,_jsxRuntime.jsxs)(_jsxRuntime.Fragment,{children:[(0,_jsxRuntime.jsx)(_sharedUi.JsModal,{visible:e,onClose:t,onMinimize:r,persistenceKey:ae,header:{showToggleButton:!0,customContent:m?(0,_jsxRuntime.jsxs)(_sharedUi.ModalHeader,{children:[(0,_jsxRuntime.jsx)(_sharedUi.ModalHeader.Navigation,{onBack:()=>h(!1)}),(0,_jsxRuntime.jsx)(_sharedUi.ModalHeader.Content,{title:"Filters",centered:!0})]}):M?(0,_jsxRuntime.jsxs)(_sharedUi.ModalHeader,{children:[(0,_jsxRuntime.jsx)(_sharedUi.ModalHeader.Navigation,{onBack:F}),(0,_jsxRuntime.jsx)(_sharedUi.ModalHeader.Content,{title:`${M.atomLabel}/${M.category}`,centered:!0})]}):c?(0,_jsxRuntime.jsxs)(_sharedUi.ModalHeader,{children:[(0,_jsxRuntime.jsx)(_sharedUi.ModalHeader.Navigation,{onBack:K}),(0,_jsxRuntime.jsx)(_sharedUi.ModalHeader.Content,{title:`${c} History`,centered:!0}),(0,_jsxRuntime.jsx)(_sharedUi.ModalHeader.Actions,{children:(0,_jsxRuntime.jsx)(_sharedUi.ToolbarCopyButton,{value:$,disabled:0===w.length,buttonStyle:styles.headerActionButton})})]}):(0,_jsxRuntime.jsxs)(_sharedUi.ModalHeader,{children:[a&&(0,_jsxRuntime.jsx)(_sharedUi.ModalHeader.Navigation,{onBack:a}),(0,_jsxRuntime.jsx)(_sharedUi.ModalHeader.Content,{title:"",children:I?(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.headerSearchContainer,children:[(0,_jsxRuntime.jsx)(_sharedUi.Search,{size:14,color:_sharedUi.macOSColors.text.secondary}),(0,_jsxRuntime.jsx)(_reactNative.TextInput,{ref:J,style:styles.headerSearchInput,placeholder:"atoms"===l?"Search atoms...":"Search events...",placeholderTextColor:_sharedUi.macOSColors.text.muted,value:N,onChangeText:z,onSubmitEditing:()=>V(!1),onBlur:()=>V(!1),autoCapitalize:"none",autoCorrect:!1,returnKeyType:"search"}),N.length>0&&(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{onPress:()=>{z(""),V(!1)},style:styles.headerSearchClear,children:(0,_jsxRuntime.jsx)(_sharedUi.X,{size:14,color:_sharedUi.macOSColors.text.secondary})})]}):(0,_jsxRuntime.jsx)(_sharedUi.TabSelector,{tabs:[{key:"atoms",label:"Atoms"+(U.length>0?` (${U.length})`:"")},{key:"events",label:"Events"+(S.length>0?` (${S.length})`:"")}],activeTab:l,onTabChange:Y})}),(0,_jsxRuntime.jsxs)(_sharedUi.ModalHeader.Actions,{children:[(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{onPress:()=>V(!0),style:styles.headerActionButton,children:(0,_jsxRuntime.jsx)(_sharedUi.Search,{size:14,color:_sharedUi.macOSColors.text.secondary})}),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{onPress:()=>h(!0),style:[styles.headerActionButton,te&&styles.headerActionButtonActive],children:(0,_jsxRuntime.jsx)(_sharedUi.Filter,{size:14,color:te?_sharedUi.macOSColors.semantic.debug:_sharedUi.macOSColors.text.secondary})}),"atoms"===l&&(0,_jsxRuntime.jsx)(_sharedUi.ToolbarCopyButton,{value:W,disabled:0===U.length,buttonStyle:styles.headerActionButton}),"events"===l&&(0,_jsxRuntime.jsxs)(_jsxRuntime.Fragment,{children:[(0,_jsxRuntime.jsx)(_sharedUi.ToolbarCopyButton,{value:G,disabled:0===S.length,buttonStyle:styles.headerActionButton}),(0,_jsxRuntime.jsx)(_sharedUi.PowerToggleButton,{isEnabled:p,onToggle:R,accessibilityLabel:"Toggle Jotai atom capture"}),(0,_jsxRuntime.jsx)(_sharedUi.ToolbarClearButton,{onPress:b,disabled:0===S.length,buttonStyle:styles.headerActionButton})]})]})]})},onModeChange:H,enablePersistence:!0,initialMode:"bottomSheet",enableGlitchEffects:!0,styles:{},footer:re,footerHeight:se,children:(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.container,children:m?(0,_jsxRuntime.jsx)(_JotaiEventFilterView.JotaiEventFilterView,{ignoredPatterns:_,onTogglePattern:Q,onAddPattern:X,atoms:C}):M&&null!==B?(0,_jsxRuntime.jsx)(_JotaiAtomDetailContent.JotaiAtomDetailContent,{change:M,changes:w,selectedIndex:B,onIndexChange:D,disableInternalFooter:!0}):c?w.length>0?(0,_jsxRuntime.jsx)(_reactNative.FlatList,{data:w,renderItem:ee,keyExtractor:Z,contentContainerStyle:styles.listContent,showsVerticalScrollIndicator:!0,removeClippedSubviews:!0,initialNumToRender:15,maxToRenderPerBatch:10,windowSize:10,scrollEnabled:!1}):(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 history yet"}),(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.emptyText,children:["Changes for ",c," will appear here."]})]}):"atoms"===l?(0,_jsxRuntime.jsx)(_JotaiAtomBrowser.JotaiAtomBrowser,{atoms:U,searchQuery:N,onViewHistory:q}):(0,_jsxRuntime.jsxs)(_jsxRuntime.Fragment,{children:[!p&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.disabledBanner,children:[(0,_jsxRuntime.jsx)(_sharedUi.Power,{size:14,color:_sharedUi.macOSColors.semantic.warning}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.disabledText,children:"Atom capture is disabled"})]}),f&&(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{style:styles.lockedBanner,onPress:L,activeOpacity:.8,children:[(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.lockedText,children:[T," older"," ",1===T?"change":"changes"," locked"]}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.upgradeBadge,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.upgradeBadgeText,children:"UPGRADE"})})]}),v.length>0?(0,_jsxRuntime.jsx)(_reactNative.FlatList,{ref:O,data:v,renderItem:ee,keyExtractor:Z,contentContainerStyle:styles.listContent,showsVerticalScrollIndicator:!0,removeClippedSubviews:!0,initialNumToRender:15,maxToRenderPerBatch:10,windowSize:10,scrollEnabled:!1}):(0,_jsxRuntime.jsx)(EventsEmptyState,{isEnabled:p})]})})}),(0,_jsxRuntime.jsx)(_sharedUi.ProUpgradeModal,{visible:i,onClose:()=>n(!1),featureName:"Full Atom History"})]})}const styles=_reactNative.StyleSheet.create({container:{flex:1,backgroundColor:_sharedUi.macOSColors.background.base},headerSearchContainer:{flexDirection:"row",alignItems:"center",backgroundColor:_sharedUi.macOSColors.background.input,borderRadius:10,borderWidth:1,borderColor:_sharedUi.macOSColors.border.default,paddingHorizontal:12,paddingVertical:5},headerSearchInput:{flex:1,color:_sharedUi.macOSColors.text.primary,fontSize:13,marginLeft:6,paddingVertical:2},headerSearchClear:{marginLeft:6,padding:4},headerActionButton:{width:32,height:32,borderRadius:8,backgroundColor:_sharedUi.macOSColors.background.hover,borderWidth:1,borderColor:_sharedUi.macOSColors.border.default,alignItems:"center",justifyContent:"center"},headerActionButtonActive:{backgroundColor:_sharedUi.macOSColors.semantic.infoBackground},disabledBanner:{flexDirection:"row",alignItems:"center",gap:8,padding:10,marginHorizontal:12,marginTop:8,backgroundColor:_sharedUi.macOSColors.semantic.warningBackground,borderRadius:8,borderWidth:1,borderColor:_sharedUi.macOSColors.semantic.warning+"20"},disabledText:{color:_sharedUi.macOSColors.semantic.warning,fontSize:11,flex:1},listContent:{paddingTop:8,paddingBottom:20},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},lockedBanner:{flexDirection:"row",alignItems:"center",gap:8,padding:10,marginHorizontal:12,marginTop:8,backgroundColor:_sharedUi.buoyColors.primary+"15",borderRadius:8,borderWidth:1,borderColor:_sharedUi.buoyColors.primary+"33"},lockedText:{color:_sharedUi.buoyColors.primary,fontSize:11,fontWeight:"500",flex:1},upgradeBadge:{backgroundColor:_sharedUi.buoyColors.primary,paddingHorizontal:8,paddingVertical:3,borderRadius:4},upgradeBadgeText:{color:"#fff",fontSize:9,fontWeight:"700",letterSpacing:.5}});
@@ -0,0 +1 @@
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,"JotaiAtomBrowser",{enumerable:!0,get:function(){return _JotaiAtomBrowser.JotaiAtomBrowser}}),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,"JotaiEventFilterView",{enumerable:!0,get:function(){return _JotaiEventFilterView.JotaiEventFilterView}}),Object.defineProperty(exports,"JotaiIcon",{enumerable:!0,get:function(){return _JotaiIcon.JotaiIcon}}),Object.defineProperty(exports,"JotaiModal",{enumerable:!0,get:function(){return _JotaiModal.JotaiModal}});var _JotaiModal=require("./JotaiModal"),_JotaiIcon=require("./JotaiIcon"),_JotaiAtomChangeItem=require("./JotaiAtomChangeItem"),_JotaiAtomDetailContent=require("./JotaiAtomDetailContent"),_JotaiAtomBrowser=require("./JotaiAtomBrowser"),_JotaiEventFilterView=require("./JotaiEventFilterView");
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.useJotaiAtomChanges=useJotaiAtomChanges;var _react=require("react"),_jotaiStateStore=require("../utils/jotaiStateStore");function useJotaiAtomChanges(){const[t,e]=(0,_react.useState)(()=>_jotaiStateStore.jotaiStateStore.getAtomChanges()),[a,o]=(0,_react.useState)(()=>_jotaiStateStore.jotaiStateStore.getAtoms()),[r,s]=(0,_react.useState)({}),[i,n]=(0,_react.useState)(()=>_jotaiStateStore.jotaiStateStore.getEnabled());(0,_react.useEffect)(()=>{const t=_jotaiStateStore.jotaiStateStore.subscribe(t=>{e(t)}),a=_jotaiStateStore.jotaiStateStore.subscribeToAtoms(t=>{o(t)});return()=>{t(),a()}},[]);const l=(0,_react.useMemo)(()=>{let e=t;if(r.searchText){const t=r.searchText.toLowerCase();e=e.filter(e=>e.atomLabel.toLowerCase().includes(t)||e.valuePreview.toLowerCase().includes(t)||e.changedKeys.some(e=>e.toLowerCase().includes(t)))}return r.atomLabels&&r.atomLabels.length>0&&(e=e.filter(t=>r.atomLabels.includes(t.atomLabel))),r.onlyWithChanges&&(e=e.filter(t=>t.hasValueChange)),e},[t,r]),S=(0,_react.useMemo)(()=>{const e=t.length,o=t.filter(t=>t.hasValueChange).length;return{totalChanges:e,changesWithValueChange:o,changesWithoutValueChange:e-o,atomCount:a.length}},[t,a]),u=(0,_react.useMemo)(()=>_jotaiStateStore.jotaiStateStore.getUniqueAtomLabels(),[a]),c=(0,_react.useCallback)(()=>{_jotaiStateStore.jotaiStateStore.clearAtomChanges()},[]),g=(0,_react.useCallback)(()=>{const t=!i;_jotaiStateStore.jotaiStateStore.setEnabled(t),n(t)},[i]),h=(0,_react.useCallback)(t=>_jotaiStateStore.jotaiStateStore.getAtomChangeById(t),[]);return{atomChanges:t,filteredChanges:l,filter:r,setFilter:s,stats:S,atoms:a,clearChanges:c,isEnabled:i,toggleCapture:g,atomLabels:u,getChangeById:h}}
@@ -0,0 +1 @@
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,"JotaiAtomBrowser",{enumerable:!0,get:function(){return _JotaiAtomBrowser.JotaiAtomBrowser}}),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,"isAtomWatched",{enumerable:!0,get:function(){return _watchAtoms.isAtomWatched}}),Object.defineProperty(exports,"jotaiStateStore",{enumerable:!0,get:function(){return _jotaiStateStore.jotaiStateStore}}),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 _JotaiModal=require("./components/JotaiModal"),_JotaiIcon=require("./components/JotaiIcon"),_JotaiAtomChangeItem=require("./components/JotaiAtomChangeItem"),_JotaiAtomDetailContent=require("./components/JotaiAtomDetailContent"),_JotaiAtomBrowser=require("./components/JotaiAtomBrowser"),_jotaiStateStore=require("./utils/jotaiStateStore"),_watchAtoms=require("./utils/watchAtoms"),_useJotaiAtomChanges=require("./hooks/useJotaiAtomChanges");
@@ -0,0 +1 @@
1
+ "use strict";
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.jotaiStateStore=void 0;const ATOM_COLORS={count:"#10B981",auth:"#8B5CF6",user:"#3B82F6",cart:"#EC4899",app:"#6366F1",ui:"#F59E0B",settings:"#14B8A6",theme:"#06B6D4",nav:"#F97316",form:"#EF4444",modal:"#A855F7",filter:"#84CC16"};function getAtomColor(t){const e=t.toLowerCase();if(ATOM_COLORS[e])return ATOM_COLORS[e];for(const[t,s]of Object.entries(ATOM_COLORS))if(e.includes(t))return s;const s=137*t.split("").reduce((t,e)=>t+e.charCodeAt(0),0)%360,n=.7*(1-Math.abs(1.2-1)),a=n*(1-Math.abs(s/60%2-1)),o=.6-n/2;let r=0,i=0,h=0;s<60?(r=n,i=a):s<120?(r=a,i=n):s<180?(i=n,h=a):s<240?(i=a,h=n):s<300?(r=a,h=n):(r=n,h=a);const l=t=>Math.round(255*(t+o)).toString(16).padStart(2,"0");return`#${l(r)}${l(i)}${l(h)}`}function formatValuePreview(t,e=40){if(void 0===t)return"undefined";if(null===t)return"null";try{if("function"==typeof t)return"(fn)";if("string"==typeof t)return t.length>e?`"${t.slice(0,e-3)}..."`:`"${t}"`;if("number"==typeof t||"boolean"==typeof t)return String(t);if(Array.isArray(t)){if(0===t.length)return"[]";const s=JSON.stringify(t);return s.length>e?`[${t.length} items]`:s}if("object"==typeof t){const s=Object.keys(t);if(0===s.length)return"{}";const n=JSON.stringify(t);return n.length<=e?n:`{ ${s.length} keys }`}return String(t).slice(0,e)}catch{return"[complex]"}}function getValueDiffSummary(t,e){if(t===e)return{summary:"no change",changedKeys:[],changedCount:0};if("object"!=typeof t||"object"!=typeof e||null===t||null===e)return{summary:"changed",changedKeys:[],changedCount:0};const s=Object.keys(t),n=Object.keys(e),a=n.filter(t=>!s.includes(t)),o=s.filter(t=>!n.includes(t)),r=[];for(const a of s)n.includes(a)&&t[a]!==e[a]&&r.push(a);const i=[...a,...o,...r],h=[];a.length>0&&h.push(`+${a.length}`),o.length>0&&h.push(`-${o.length}`),r.length>0&&h.push(`~${r.length}`);const l=i.length;return 0===h.length?{summary:"nested change",changedKeys:[],changedCount:0}:{summary:`${h.join(" ")} ${1===l?"key":"keys"}`,changedKeys:i,changedCount:l}}class JotaiStateStore{atomChanges=[];atoms=new Map;listeners=new Set;atomListeners=new Set;maxChanges=200;idCounter=0;isEnabled=!0;addAtomChange(t){if(!this.isEnabled)return;const{atomLabel:e,prevValue:s,nextValue:n,category:a="write"}=t,o=s!==n,{summary:r,changedKeys:i,changedCount:h}=getValueDiffSummary(s,n),l=formatValuePreview(n),u={id:`${Date.now()}-${++this.idCounter}`,atomLabel:e,timestamp:Date.now(),prevValue:s,nextValue:n,hasValueChange:o,category:a,changedKeys:i,changedKeysCount:h,diffSummary:r,valuePreview:l,isSlowUpdate:!1};this.atomChanges=[u,...this.atomChanges].slice(0,this.maxChanges);const g=this.atoms.get(e);g&&g.changeCount++,this.notifyListeners(),this.notifyAtomListeners()}getAtomChanges(){return[...this.atomChanges]}getAtomChangeById(t){return this.atomChanges.find(e=>e.id===t)}clearAtomChanges(){this.atomChanges=[];for(const t of this.atoms.values())t.changeCount=0;this.notifyListeners(),this.notifyAtomListeners()}registerAtom(t,e){if(this.atoms.has(t))return;const s={label:t,changeCount:0,color:getAtomColor(t),getValue:e};this.atoms.set(t,s),this.notifyAtomListeners()}unregisterAtom(t){this.atoms.delete(t),this.notifyAtomListeners()}getAtoms(){return Array.from(this.atoms.values())}getAtom(t){return this.atoms.get(t)}getAtomColor(t){return this.atoms.get(t)?.color??getAtomColor(t)}filterAtomChanges(t){let e=[...this.atomChanges];if(t.searchText){const s=t.searchText.toLowerCase();e=e.filter(t=>t.atomLabel.toLowerCase().includes(s)||t.valuePreview.toLowerCase().includes(s)||t.changedKeys.some(t=>t.toLowerCase().includes(s)))}return t.atomLabels&&t.atomLabels.length>0&&(e=e.filter(e=>t.atomLabels.includes(e.atomLabel))),t.onlyWithChanges&&(e=e.filter(t=>t.hasValueChange)),e}getStats(){const t=this.atomChanges.length,e=this.atomChanges.filter(t=>t.hasValueChange).length;return{totalChanges:t,changesWithValueChange:e,changesWithoutValueChange:t-e,atomCount:this.atoms.size}}getUniqueAtomLabels(){return Array.from(this.atoms.keys()).sort()}setEnabled(t){this.isEnabled=t}getEnabled(){return this.isEnabled}setMaxChanges(t){this.maxChanges=t,this.atomChanges.length>t&&(this.atomChanges=this.atomChanges.slice(0,t),this.notifyListeners())}subscribe(t){return this.listeners.add(t),()=>this.listeners.delete(t)}subscribeToAtoms(t){return this.atomListeners.add(t),()=>this.atomListeners.delete(t)}notifyListeners(){const t=this.getAtomChanges();this.listeners.forEach(e=>e(t))}notifyAtomListeners(){const t=this.getAtoms();this.atomListeners.forEach(e=>e(t))}}const jotaiStateStore=exports.jotaiStateStore=new JotaiStateStore;
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.isAtomWatched=isAtomWatched,exports.watchAtoms=watchAtoms,exports.watchDefaultStoreAtoms=watchDefaultStoreAtoms;var _jotaiStateStore=require("./jotaiStateStore");function watchAtoms(t,e,o){const a=!1!==o?.enabled,r=[];for(const[o,i]of Object.entries(e)){const e=i,c=Symbol.for(`@@buoy-jotai/watched/${o}`);if(e[c])continue;let s;e[c]=!0;try{s=t.get(i)}catch{s=void 0}_jotaiStateStore.jotaiStateStore.registerAtom(o,()=>{try{return t.get(i)}catch{return}}),a&&_jotaiStateStore.jotaiStateStore.addAtomChange({atomLabel:o,prevValue:void 0,nextValue:s,category:"initial"});const n=t.sub(i,()=>{try{const e=t.get(i);_jotaiStateStore.jotaiStateStore.addAtomChange({atomLabel:o,prevValue:s,nextValue:e,category:"write"}),s=e}catch{}});r.push(()=>{n(),delete e[c],_jotaiStateStore.jotaiStateStore.unregisterAtom(o)})}return()=>r.forEach(t=>t())}function watchDefaultStoreAtoms(t,e){let o;try{const{getDefaultStore:t}=require("jotai/vanilla");o=t()}catch{try{const{getDefaultStore:t}=require("jotai");o=t()}catch{return console.warn("[@buoy-gg/jotai] Could not find getDefaultStore from jotai. Pass the store explicitly via watchAtoms(store, atoms) instead."),()=>{}}}return watchAtoms(o,t,e)}function isAtomWatched(t){return void 0!==_jotaiStateStore.jotaiStateStore.getAtom(t)}
@@ -0,0 +1 @@
1
+ {"type":"commonjs"}
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.createJotaiTool=createJotaiTool,exports.jotaiToolPreset=void 0;var _JotaiModal=require("./jotai/components/JotaiModal"),_JotaiIcon=require("./jotai/components/JotaiIcon"),_jsxRuntime=require("react/jsx-runtime");const jotaiToolPreset=exports.jotaiToolPreset={id:"jotai",name:"JOTAI",description:"Jotai atom & state inspector",slot:"both",icon:({size:o})=>(0,_jsxRuntime.jsx)(_JotaiIcon.JotaiIcon,{size:o}),component:_JotaiModal.JotaiModal,props:{enableSharedModalDimensions:!1}};function createJotaiTool(o){return{id:o?.id||"jotai",name:o?.name||"JOTAI",description:o?.description||"Jotai atom & state inspector",slot:"both",icon:({size:e})=>(0,_jsxRuntime.jsx)(_JotaiIcon.JotaiIcon,{size:e,color:o?.iconColor}),component:_JotaiModal.JotaiModal,props:{enableSharedModalDimensions:void 0!==o?.enableSharedModalDimensions&&o.enableSharedModalDimensions}}}
@@ -0,0 +1 @@
1
+ "use strict";export{jotaiToolPreset,createJotaiTool}from"./preset";export{watchAtoms}from"./jotai/utils/watchAtoms";export{watchDefaultStoreAtoms}from"./jotai/utils/watchAtoms";export{isAtomWatched}from"./jotai/utils/watchAtoms";export{useJotaiAtomChanges}from"./jotai/hooks/useJotaiAtomChanges";export{JotaiModal}from"./jotai/components/JotaiModal";export{JotaiAtomChangeItem}from"./jotai/components/JotaiAtomChangeItem";export{JotaiAtomDetailContent,JotaiAtomDetailFooter}from"./jotai/components/JotaiAtomDetailContent";export{JotaiIcon,JOTAI_ICON_COLOR}from"./jotai/components/JotaiIcon";export{jotaiStateStore}from"./jotai/utils/jotaiStateStore";
@@ -0,0 +1 @@
1
+ "use strict";import{useState,useMemo,useCallback}from"react";import{View,Text,StyleSheet,ScrollView,TouchableOpacity}from"react-native";import{CompactRow,macOSColors,buoyColors,Box,ExpandedInfoRow,PillBadge,parseValue}from"@buoy-gg/shared-ui";import{DataViewer}from"@buoy-gg/shared-ui/dataViewer";import{jotaiStateStore}from"../utils/jotaiStateStore";import{jsx as _jsx,jsxs as _jsxs}from"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 o=e.getValue(),r=useMemo(()=>{if(o&&"object"==typeof o){const e={};for(const[t,r]of Object.entries(o))"function"!=typeof r&&(e[t]=r);return parseValue(e)}return parseValue(o)},[o]);return _jsxs(View,{style:expandedStyles.container,children:[_jsx(ExpandedInfoRow,{label:"Type",children:_jsx(PillBadge,{color:e.color,children:"JOTAI"})}),e.changeCount>0&&_jsxs(ExpandedInfoRow,{label:"Changes",children:[_jsx(PillBadge,{color:buoyColors.warning,children:String(e.changeCount)}),_jsx(TouchableOpacity,{onPress:()=>t(e.label),style:expandedStyles.viewHistoryButton,hitSlop:{top:6,bottom:6,left:6,right:6},children:_jsx(Text,{style:[expandedStyles.viewHistoryText,{color:e.color}],children:"view history →"})})]}),_jsx(View,{style:expandedStyles.dataContainer,children:r&&"object"==typeof r?_jsx(DataViewer,{title:"",data:r,showTypeFilter:!0}):_jsx(Text,{style:expandedStyles.primitiveText,children:String(o??"undefined")})})]})}function EmptyBrowserState(){return _jsxs(View,{style:styles.emptyState,children:[_jsx(Box,{size:32,color:macOSColors.text.muted}),_jsx(Text,{style:styles.emptyTitle,children:"No atoms registered"}),_jsx(Text,{style:styles.emptyText,children:"Use watchAtoms(store, { atomName }) to register your Jotai atoms.\nThey will appear here with their current value."})]})}export function JotaiAtomBrowser({atoms:e,searchQuery:t,onViewHistory:o}){const[r,n]=useState(null),s=useMemo(()=>{if(!t)return e;const o=t.toLowerCase();return e.filter(e=>e.label.toLowerCase().includes(o))},[e,t]),l=useCallback(e=>{n(t=>t===e.label?null:e.label)},[]);return 0!==s.length||t?0===s.length&&t?_jsxs(View,{style:styles.emptyState,children:[_jsx(Text,{style:styles.emptyTitle,children:"No matching atoms"}),_jsxs(Text,{style:styles.emptyText,children:['No atoms match "',t,'"']})]}):_jsxs(ScrollView,{style:styles.container,contentContainerStyle:styles.scrollContent,showsVerticalScrollIndicator:!0,children:[_jsxs(View,{style:styles.sectionHeader,children:[_jsx(Text,{style:styles.sectionTitle,children:"ATOMS"}),_jsx(View,{style:styles.sectionCountBadge,children:_jsx(Text,{style:styles.sectionCountText,children:s.length})})]}),s.map(e=>{const t=r===e.label,n=getValuePreview(e),s=jotaiStateStore.getAtomColor(e.label);return _jsxs(View,{style:styles.atomRowWrapper,children:[_jsx(CompactRow,{statusDotColor:s,statusLabel:e.label,statusSublabel:getValueType(e),primaryText:n,showChevron:!0,isExpanded:t,onPress:()=>l(e),expandedContent:t?_jsx(AtomExpandedContent,{atom:e,onViewHistory:o}):void 0}),e.changeCount>0&&_jsx(View,{style:[styles.absCountBadge,{backgroundColor:s+"22",borderColor:s+"55"}],pointerEvents:"none",children:_jsx(Text,{style:[styles.absCountText,{color:s}],children:String(e.changeCount)})})]},e.label)})]}):_jsx(EmptyBrowserState,{})}const styles=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:macOSColors.text.muted},sectionCountBadge:{backgroundColor:buoyColors.primary+"26",paddingHorizontal:8,paddingVertical:2,borderRadius:4},sectionCountText:{fontSize:10,fontWeight:"700",color:buoyColors.primary,fontFamily:"monospace"},emptyState:{alignItems:"center",paddingVertical:40},emptyTitle:{color:macOSColors.text.primary,fontSize:14,fontWeight:"600",marginTop:12,marginBottom:6},emptyText:{color:macOSColors.text.muted,fontSize:12,textAlign:"center",lineHeight:18}}),expandedStyles=StyleSheet.create({container:{gap:10},viewHistoryButton:{marginLeft:4},viewHistoryText:{fontSize:10,fontWeight:"600",fontFamily:"monospace"},dataContainer:{backgroundColor:buoyColors.base,borderRadius:6,borderWidth:1,borderColor:buoyColors.border,overflow:"hidden",minHeight:60},primitiveText:{color:buoyColors.text,fontSize:12,fontFamily:"monospace",padding:14}});
@@ -0,0 +1 @@
1
+ "use strict";import{View,Text,StyleSheet}from"react-native";import{CompactRow,buoyColors,Zap,formatRelativeTime}from"@buoy-gg/shared-ui";import{jotaiStateStore}from"../utils/jotaiStateStore";import{jsx as _jsx,jsxs as _jsxs}from"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?buoyColors.textMuted: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()"}export function JotaiAtomChangeItem({change:e,onPress:t}){const o=getCategoryColor(e.category,e.atomLabel),a=getStatusLabel(e.category,e.atomLabel),r=getSublabel(e),n=getPrimaryText(e),i=getBadgeText(e),s=e.hasValueChange?_jsxs(View,{style:styles.badgeContainer,children:[_jsx(Text,{style:[styles.badgeText,{color:o}],children:i}),_jsx(View,{style:styles.changeBadge,children:_jsx(Zap,{size:12,color:buoyColors.warning})})]}):void 0;return _jsx(CompactRow,{statusDotColor:o,statusLabel:a,statusSublabel:r,primaryText:n,bottomRightText:formatRelativeTime(e.timestamp),customBadge:s,badgeText:s?void 0:i,badgeColor:o,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}});
@@ -0,0 +1 @@
1
+ "use strict";import React,{memo,useState,useCallback,useMemo}from"react";import{View,Text,StyleSheet,ScrollView,TouchableOpacity}from"react-native";import{macOSColors,buoyColors,EventStepperFooter,formatRelativeTime,parseValue,Info,Zap,FileText,Database,GitBranch,copyToClipboard,ProUpgradeModal,DiffModeTabs,CompareBar}from"@buoy-gg/shared-ui";import{DataViewer,SplitDiffViewer,TreeDiffViewer,diffThemes}from"@buoy-gg/shared-ui/dataViewer";import{useIsPro}from"@buoy-gg/license";import{jotaiStateStore}from"../utils/jotaiStateStore";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";const VIEW_CONFIGS=[{key:"change",label:"CHANGE",icon:FileText,activeColor:macOSColors.semantic.warning},{key:"value",label:"VALUE",icon:Database,activeColor:macOSColors.semantic.info},{key:"diff",label:"DIFF",icon:GitBranch,activeColor:macOSColors.semantic.success}];function DetailViewToggle({activeView:e,onViewChange:o,diffDisabled:t}){return _jsx(View,{style:toggleStyles.container,children:VIEW_CONFIGS.map(a=>{const r=e===a.key,l="diff"===a.key&&t,i=a.icon;return _jsx(TouchableOpacity,{style:[toggleStyles.card,r&&[toggleStyles.cardActive,{borderColor:a.activeColor}],l&&toggleStyles.cardDisabled],onPress:()=>!l&&o(a.key),activeOpacity:.7,children:_jsxs(View,{style:toggleStyles.cardContent,children:[_jsx(i,{size:14,color:r?a.activeColor:l?macOSColors.text.muted:macOSColors.text.secondary}),_jsx(Text,{style:[toggleStyles.cardLabel,r&&{color:a.activeColor},l&&{color:macOSColors.text.muted}],children:a.label})]})},a.key)})})}function getCategoryInfo(e){return"initial"===e?{label:"INITIAL",color:buoyColors.textMuted,bgColor:buoyColors.textMuted+"26"}:{label:"WRITE",color:buoyColors.success,bgColor:buoyColors.success+"26"}}function formatTime(e){const o=new Date(e);return`${o.getHours().toString().padStart(2,"0")}:${o.getMinutes().toString().padStart(2,"0")}:${o.getSeconds().toString().padStart(2,"0")}.${o.getMilliseconds().toString().padStart(3,"0")}`}function formatTimestamp(e){return new Date(e).toLocaleTimeString("en-US",{hour12:!1,hour:"2-digit",minute:"2-digit",second:"2-digit"})}function getValueType(e){return null===e?"null":void 0===e?"undefined":Array.isArray(e)?"array":typeof e}function getChangeLabel(e){return"initial"===e?"INIT":"WRITE"}const DIFF_MODE_TABS=[{key:"tree",label:"TREE VIEW"},{key:"split",label:"SPLIT VIEW"}],JotaiAtomInfoView=memo(function({change:e}){const o=useIsPro(),[t,a]=useState(!1),r=getCategoryInfo(e.category),l=jotaiStateStore.getAtomColor(e.atomLabel),i=useCallback(async()=>{o?await copyToClipboard(e.nextValue):a(!0)},[e.nextValue,o]);return _jsxs(ScrollView,{style:infoStyles.container,contentContainerStyle:infoStyles.content,showsVerticalScrollIndicator:!1,children:[_jsxs(View,{style:infoStyles.card,children:[_jsx(View,{style:infoStyles.sectionHeader,children:_jsxs(View,{style:infoStyles.sectionHeaderLeft,children:[_jsx(Info,{size:14,color:buoyColors.primary}),_jsx(Text,{style:infoStyles.sectionTitle,children:"CHANGE INFO"})]})}),_jsxs(View,{style:infoStyles.cardContent,children:[_jsxs(View,{style:infoStyles.infoRow,children:[_jsx(Text,{style:infoStyles.infoLabel,children:"Atom"}),_jsx(Text,{style:[infoStyles.infoValue,infoStyles.infoValueMono,{color:l}],numberOfLines:1,ellipsizeMode:"middle",children:e.atomLabel})]}),_jsxs(View,{style:infoStyles.infoRow,children:[_jsx(Text,{style:infoStyles.infoLabel,children:"Time"}),_jsx(Text,{style:[infoStyles.infoValue,infoStyles.infoValueMono],children:formatTime(e.timestamp)})]}),_jsxs(View,{style:infoStyles.badgeRow,children:[_jsx(View,{style:[infoStyles.categoryBadge,{backgroundColor:r.bgColor}],children:_jsx(Text,{style:[infoStyles.categoryText,{color:r.color}],children:r.label})}),e.hasValueChange?_jsxs(View,{style:infoStyles.changesBadge,children:[_jsx(Zap,{size:10,color:buoyColors.success}),_jsx(Text,{style:infoStyles.changesText,children:e.diffSummary||"changed"})]}):_jsx(View,{style:infoStyles.noChangesBadge,children:_jsx(Text,{style:infoStyles.noChangesText,children:"no change"})})]})]})]}),e.changedKeys.length>0&&_jsxs(View,{style:infoStyles.card,children:[_jsxs(View,{style:infoStyles.sectionHeader,children:[_jsxs(View,{style:infoStyles.sectionHeaderLeft,children:[_jsx(Zap,{size:14,color:buoyColors.primary}),_jsx(Text,{style:infoStyles.sectionTitle,children:"CHANGED KEYS"})]}),_jsx(View,{style:infoStyles.countBadge,children:_jsx(Text,{style:infoStyles.countText,children:e.changedKeys.length})})]}),_jsx(View,{style:infoStyles.cardContent,children:_jsx(View,{style:infoStyles.keysContainer,children:e.changedKeys.map(e=>_jsx(View,{style:infoStyles.keyBadge,children:_jsx(Text,{style:infoStyles.keyText,children:e})},e))})})]}),_jsx(View,{style:infoStyles.actionsRow,children:_jsx(View,{style:[infoStyles.actionButton,infoStyles.actionButtonCopy],onTouchEnd:i,children:_jsx(Text,{style:[infoStyles.actionButtonText,{color:buoyColors.primary}],children:"COPY VALUE"})})}),_jsx(ProUpgradeModal,{visible:t,onClose:()=>a(!1),featureName:"Copy"})]})});export function JotaiAtomDetailContent({change:e,changes:o,selectedIndex:t,onIndexChange:a,disableInternalFooter:r=!1}){const[l,i]=useState("change"),[n,s]=useState("tree"),c=o.length,d=jotaiStateStore.getAtomColor(e.atomLabel),y=getChangeLabel(e.category),g=getValueType(e.nextValue),u=c-t,f=t<c-1?t+1:null,m=null!==f?o[f]:null,x=u-1,h=useMemo(()=>({index:f??0,label:x>0?`#${x}`:"Initial",timestamp:m?formatTimestamp(m.timestamp):"",relativeTime:m?formatRelativeTime(new Date(m.timestamp)):"value",badge:m?_jsx(View,{style:[styles.changeBadgeSmall,{backgroundColor:`${jotaiStateStore.getAtomColor(m.atomLabel)}20`}],children:_jsx(Text,{style:[styles.changeTextSmall,{color:jotaiStateStore.getAtomColor(m.atomLabel)}],children:getChangeLabel(m.category)})}):void 0}),[f,m,x]),p=useMemo(()=>({index:t,label:`#${u}`,timestamp:formatTimestamp(e.timestamp),relativeTime:formatRelativeTime(new Date(e.timestamp)),badge:_jsx(View,{style:[styles.changeBadgeSmall,{backgroundColor:`${d}20`}],children:_jsx(Text,{style:[styles.changeTextSmall,{color:d}],children:y})})}),[t,e.timestamp,d,y,u]),b=useCallback(()=>{const o=parseValue(e.nextValue);return _jsxs(View,{style:styles.contentCard,children:[_jsxs(View,{style:styles.valueHeader,children:[_jsx(Text,{style:styles.valueLabel,children:"VALUE AFTER CHANGE"}),_jsxs(View,{style:styles.valueHeaderBadges,children:[_jsx(View,{style:[styles.changeBadge,{backgroundColor:`${d}20`}],children:_jsx(Text,{style:[styles.changeText,{color:d}],children:y})}),_jsx(View,{style:styles.typeBadge,children:_jsx(Text,{style:styles.typeText,children:g.toUpperCase()})})]})]}),_jsx(View,{style:styles.valueBox,children:"object"!==g&&"array"!==g||!o?_jsx(Text,{style:styles.valueText,children:null===o?"null":void 0===o?"undefined":"string"===g?`"${o}"`:String(o)}):_jsx(DataViewer,{title:"",data:o,showTypeFilter:!1})})]})},[e.nextValue,d,y,g]),C=useCallback(()=>{const o=parseValue(e.prevValue),t=parseValue(e.nextValue);return"split"===n?_jsx(ScrollView,{style:{flex:1},showsVerticalScrollIndicator:!0,children:_jsx(SplitDiffViewer,{oldValue:o,newValue:t,theme:diffThemes.devToolsDefault,options:{hideLineNumbers:!1,disableWordDiff:!1,showDiffOnly:!1,compareMethod:"words",contextLines:3},showThemeName:!1})}):_jsx(TreeDiffViewer,{oldValue:o,newValue:t})},[e.prevValue,e.nextValue,n]),S=useCallback(()=>{a(Math.min(c-1,t+1))},[t,c,a]),V=useCallback(()=>{a(Math.max(0,t-1))},[t,a]),w=c<=1;return _jsxs(View,{style:styles.container,children:[_jsx(DetailViewToggle,{activeView:l,onViewChange:i,diffDisabled:w}),_jsxs(View,{style:styles.contentArea,children:["change"===l&&_jsx(JotaiAtomInfoView,{change:e}),"value"===l&&_jsx(View,{style:styles.stateContainer,children:b()}),"diff"===l&&_jsxs(View,{style:styles.diffContainer,children:[_jsx(DiffModeTabs,{tabs:DIFF_MODE_TABS,activeTab:n,onTabChange:s}),_jsx(CompareBar,{leftEvent:h,rightEvent:p}),_jsx(View,{style:styles.diffContent,children:C()})]})]}),!r&&c>1&&_jsx(EventStepperFooter,{currentIndex:u-1,totalItems:c,onPrevious:S,onNext:V,itemLabel:"Change",subtitle:formatRelativeTime(new Date(e.timestamp)),absolute:!0})]})}export function JotaiAtomDetailFooter({change:e,changes:o,selectedIndex:t,onIndexChange:a}){const r=o.length;return r<=1?null:_jsx(EventStepperFooter,{currentIndex:r-t-1,totalItems:r,onPrevious:()=>a(Math.min(r-1,t+1)),onNext:()=>a(Math.max(0,t-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"}}),toggleStyles=StyleSheet.create({container:{flexDirection:"row",gap:8,padding:14,backgroundColor:macOSColors.background.base},card:{flex:1,backgroundColor:macOSColors.background.card,borderRadius:12,borderWidth:1,borderColor:macOSColors.border.default,paddingVertical:10,paddingHorizontal:10,justifyContent:"center"},cardActive:{borderWidth:1.5,backgroundColor:"rgba(0, 184, 230, 0.05)"},cardDisabled:{opacity:.5},cardContent:{flexDirection:"row",alignItems:"center",gap:6},cardLabel:{fontSize:10,fontWeight:"700",letterSpacing:.5,color:macOSColors.text.secondary}}),infoStyles=StyleSheet.create({container:{flex:1},content:{padding:8,paddingBottom:100,gap:16},card:{backgroundColor:buoyColors.card,borderRadius:6,borderWidth:1,borderColor:buoyColors.primary+"4D",overflow:"hidden",shadowColor:buoyColors.primary,shadowOffset:{width:0,height:0},shadowOpacity:.1,shadowRadius:6},sectionHeader:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",paddingHorizontal:12,paddingVertical:10,borderBottomWidth:1,borderBottomColor:buoyColors.primary+"33",backgroundColor:buoyColors.primary+"15"},sectionHeaderLeft:{flexDirection:"row",alignItems:"center",gap:6},sectionTitle:{fontSize:12,fontWeight:"600",letterSpacing:.5,color:buoyColors.primary,fontFamily:"monospace"},cardContent:{padding:14,gap:10},infoRow:{flexDirection:"row",alignItems:"center",justifyContent:"space-between"},infoLabel:{fontSize:11,color:buoyColors.textMuted,fontWeight:"500"},infoValue:{fontSize:11,color:buoyColors.text,fontWeight:"500",flex:1,textAlign:"right",marginLeft:12},infoValueMono:{fontFamily:"monospace"},badgeRow:{flexDirection:"row",flexWrap:"wrap",gap:8,marginTop:6},categoryBadge:{paddingHorizontal:8,paddingVertical:3,borderRadius:4},categoryText:{fontSize:9,fontWeight:"700",letterSpacing:.3},changesBadge:{flexDirection:"row",alignItems:"center",gap:4,paddingHorizontal:8,paddingVertical:3,borderRadius:4,backgroundColor:buoyColors.success+"26"},changesText:{fontSize:9,fontWeight:"600",color:buoyColors.success},noChangesBadge:{paddingHorizontal:8,paddingVertical:3,borderRadius:4,backgroundColor:buoyColors.input},noChangesText:{fontSize:9,fontWeight:"600",color:buoyColors.textMuted},keysContainer:{flexDirection:"row",flexWrap:"wrap",gap:6},keyBadge:{paddingHorizontal:8,paddingVertical:4,borderRadius:4,backgroundColor:buoyColors.primary+"20",borderWidth:1,borderColor:buoyColors.primary+"40"},keyText:{fontSize:11,fontWeight:"600",color:buoyColors.primary,fontFamily:"monospace"},countBadge:{paddingHorizontal:8,paddingVertical:3,borderRadius:4,backgroundColor:buoyColors.primary+"26"},countText:{fontSize:9,fontWeight:"700",color:buoyColors.primary,fontFamily:"monospace"},actionsRow:{flexDirection:"row",gap:12},actionButton:{paddingHorizontal:14,paddingVertical:8,borderRadius:8,borderWidth:1},actionButtonCopy:{borderColor:buoyColors.primary+"40",backgroundColor:buoyColors.primary+"15"},actionButtonText:{fontSize:10,fontWeight:"700",fontFamily:"monospace",letterSpacing:.3}});
@@ -0,0 +1 @@
1
+ "use strict";import{useState}from"react";import{View,Text,TextInput,StyleSheet,ScrollView,TouchableOpacity}from"react-native";import{SectionHeader,macOSColors,buoyColors,Filter,X}from"@buoy-gg/shared-ui";import{jotaiStateStore}from"../utils/jotaiStateStore";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";function getAtomColorForPattern(e,o){const t=o.find(o=>o.label.toLowerCase().includes(e.toLowerCase()));return t?t.color:null}export function JotaiEventFilterView({ignoredPatterns:e,onTogglePattern:o,onAddPattern:t,atoms:r}){const[l,s]=useState("");return _jsxs(ScrollView,{style:styles.container,contentContainerStyle:styles.scrollContent,showsVerticalScrollIndicator:!1,nestedScrollEnabled:!0,children:[_jsxs(View,{style:styles.section,children:[_jsxs(SectionHeader,{children:[_jsx(SectionHeader.Icon,{icon:Filter,color:buoyColors.textSecondary,size:12}),_jsx(SectionHeader.Title,{children:"REGISTERED ATOMS"})]}),0===r.length?_jsx(Text,{style:styles.emptyText,children:"No atoms registered yet."}):_jsx(ScrollView,{style:styles.atomList,contentContainerStyle:styles.atomListContent,nestedScrollEnabled:!0,children:r.map(t=>{const r=jotaiStateStore.getAtomColor(t.label),l=Array.from(e).some(e=>t.label.toLowerCase().includes(e.toLowerCase()));return _jsxs(TouchableOpacity,{style:[styles.atomRow,l&&styles.atomRowFiltered],onPress:()=>o(t.label),activeOpacity:.7,children:[_jsx(View,{style:[styles.atomDot,{backgroundColor:r}]}),_jsx(Text,{style:[styles.atomRowText,{color:r},l&&styles.atomRowTextFiltered],numberOfLines:1,children:t.label}),_jsx(Text,l?{style:styles.filteredLabel,children:"filtered"}:{style:[styles.addLabel,{color:r}],children:"+ add"})]},t.label)})}),_jsx(View,{style:styles.addInputWrapper,children:_jsx(TextInput,{value:l,onChangeText:s,onSubmitEditing:()=>{const o=l.trim();o&&!e.has(o)&&(t(o),s(""))},placeholder:"Type a pattern and press Enter...",placeholderTextColor:macOSColors.text.muted,returnKeyType:"done",autoCapitalize:"none",autoCorrect:!1,style:styles.patternInput})})]}),e.size>0&&_jsxs(View,{style:styles.section,children:[_jsxs(SectionHeader,{children:[_jsx(SectionHeader.Icon,{icon:Filter,color:buoyColors.textSecondary,size:12}),_jsx(SectionHeader.Title,{children:"ACTIVE FILTERS"})]}),_jsx(View,{style:styles.patternList,children:Array.from(e).map(e=>{const t=getAtomColorForPattern(e,r);return _jsxs(TouchableOpacity,{style:styles.patternRow,onPress:()=>o(e),activeOpacity:.8,children:[t?_jsx(View,{style:[styles.atomDot,{backgroundColor:t}]}):null,_jsx(Text,{style:[styles.patternText,t?{color:t}:null],numberOfLines:1,children:e}),_jsx(X,{size:12,color:buoyColors.primary+"80"})]},e)})})]}),_jsxs(View,{style:styles.section,children:[_jsxs(SectionHeader,{children:[_jsx(SectionHeader.Icon,{icon:Filter,color:buoyColors.textSecondary,size:12}),_jsx(SectionHeader.Title,{children:"HOW ATOM FILTERS WORK"})]}),_jsx(Text,{style:styles.howItWorksText,children:"Patterns hide matching atoms from both the Atoms tab and the Events tab. Tap an atom above to quickly add it as a filter."}),_jsxs(View,{style:styles.examplesContainer,children:[_jsx(Text,{style:styles.examplesTitle,children:"EXAMPLES:"}),["• count -> hides countAtom from atoms & events","• auth -> hides authAtom, authStatusAtom","• user -> hides userAtom from both tabs"].map(e=>_jsx(Text,{style:styles.exampleItem,children:e},e))]})]})]})}const styles=StyleSheet.create({container:{flex:1,backgroundColor:buoyColors.base},scrollContent:{paddingTop:16,paddingHorizontal:16,paddingBottom:24,gap:16},section:{backgroundColor:buoyColors.card,borderRadius:16,borderWidth:1,borderColor:buoyColors.border,overflow:"hidden"},atomList:{maxHeight:180},atomListContent:{paddingHorizontal:16,paddingTop:8,paddingBottom:16,gap:10},atomRow:{flexDirection:"row",alignItems:"center",gap:10,paddingVertical:10,paddingHorizontal:12,backgroundColor:buoyColors.hover,borderRadius:8,borderWidth:1,borderColor:buoyColors.border},atomRowFiltered:{opacity:.45},atomDot:{width:7,height:7,borderRadius:3.5},atomRowText:{flex:1,fontSize:12,fontWeight:"600",fontFamily:"monospace"},atomRowTextFiltered:{color:macOSColors.text.muted,textDecorationLine:"line-through"},filteredLabel:{fontSize:10,fontWeight:"500",color:macOSColors.text.disabled,fontFamily:"monospace"},addLabel:{fontSize:10,fontWeight:"600",fontFamily:"monospace"},addInputWrapper:{paddingHorizontal:16,paddingTop:8,paddingBottom:8},patternList:{paddingHorizontal:16,paddingBottom:16,gap:8},patternRow:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",paddingVertical:10,paddingHorizontal:12,backgroundColor:buoyColors.hover,borderRadius:8,borderWidth:1,borderColor:buoyColors.border,gap:8},patternText:{flex:1,fontSize:12,fontFamily:"monospace",color:buoyColors.text},howItWorksText:{fontSize:11,color:buoyColors.textSecondary,lineHeight:16,marginTop:8,paddingHorizontal:16,fontFamily:"monospace"},examplesContainer:{paddingTop:8,paddingHorizontal:16,paddingBottom:16,borderTopWidth:1,borderTopColor:buoyColors.border,marginTop:12},examplesTitle:{fontSize:10,fontWeight:"600",color:buoyColors.textMuted,fontFamily:"monospace",letterSpacing:.5,marginBottom:6},exampleItem:{fontSize:10,color:buoyColors.textMuted,fontFamily:"monospace",lineHeight:16},emptyText:{fontSize:11,color:macOSColors.text.muted,paddingHorizontal:16,paddingVertical:12,fontFamily:"monospace"},patternInput:{borderWidth:1,borderColor:buoyColors.primary+"40",borderRadius:8,paddingHorizontal:12,paddingVertical:8,fontSize:12,color:buoyColors.text,fontFamily:"monospace",backgroundColor:buoyColors.input}});
@@ -0,0 +1 @@
1
+ "use strict";import{View,Text}from"react-native";import{jsx as _jsx}from"react/jsx-runtime";const JOTAI_ICON_COLOR="#6C47FF";export function JotaiIcon({size:t,color:e}){return _jsx(View,{style:{width:t,height:t,justifyContent:"center",alignItems:"center"},children:_jsx(Text,{style:{fontSize:.75*t,color:e||"#6C47FF",fontWeight:"700"},children:"J"})})}export{JOTAI_ICON_COLOR};
@@ -0,0 +1 @@
1
+ "use strict";import{useState,useMemo,useRef,useCallback}from"react";import{View,Text,StyleSheet,FlatList,TextInput,TouchableOpacity}from"react-native";import{JsModal,ModalHeader,TabSelector,macOSColors,buoyColors,Search,Filter,Power,X,Box,devToolsStorageKeys,ProUpgradeModal,PowerToggleButton,ToolbarCopyButton,ToolbarClearButton,truncatePayload}from"@buoy-gg/shared-ui";import{useIsPro}from"@buoy-gg/license";import{useJotaiAtomChanges}from"../hooks/useJotaiAtomChanges";import{JotaiAtomChangeItem}from"./JotaiAtomChangeItem";import{JotaiAtomDetailContent,JotaiAtomDetailFooter}from"./JotaiAtomDetailContent";import{JotaiAtomBrowser}from"./JotaiAtomBrowser";import{JotaiEventFilterView}from"./JotaiEventFilterView";import{jsx as _jsx,jsxs as _jsxs,Fragment as _Fragment}from"react/jsx-runtime";const FREE_TIER_CHANGE_LIMIT=25;function EventsEmptyState({isEnabled:e}){return _jsxs(View,{style:styles.emptyState,children:[_jsx(Box,{size:32,color:macOSColors.text.muted}),_jsx(Text,{style:styles.emptyTitle,children:"No atom changes"}),_jsx(Text,{style:styles.emptyText,children:e?"Atom changes will appear here as values update.":"Enable capture to start recording atom changes"})]})}export function JotaiModal({visible:e,onClose:t,onBack:o,onMinimize:a,enableSharedModalDimensions:l=!1}){const r=useIsPro(),[s,n]=useState(!1),[i,d]=useState("atoms"),[c,u]=useState(null),[m,h]=useState(!1),[g,y]=useState(new Set),{filteredChanges:x,filter:b,setFilter:C,atoms:p,clearChanges:S,isEnabled:_,toggleCapture:j}=useJotaiAtomChanges(),T=useMemo(()=>0===g.size?x:x.filter(e=>!Array.from(g).some(t=>e.atomLabel.toLowerCase().includes(t.toLowerCase()))),[x,g]),f=useMemo(()=>0===g.size?p:p.filter(e=>!Array.from(g).some(t=>e.label.toLowerCase().includes(t.toLowerCase()))),[p,g]),w=useMemo(()=>r?T:T.slice(0,25),[T,r]),B=useMemo(()=>r?0:Math.max(0,T.length-25),[T.length,r]),k=B>0,v=useMemo(()=>c?w.filter(e=>e.atomLabel===c):w,[w,c]),[A,M]=useState(null),V=useMemo(()=>{if(null===A)return null;const e=v.findIndex(e=>e.id===A);return e>=0?e:null},[A,v]),O=null!==V?v[V]:null,[I,P]=useState(""),[z,E]=useState(!1),H=useRef(null),J=useRef(null),F=useCallback(e=>{},[]),L=e=>{P(e),"events"===i&&C(t=>({...t,searchText:e}))},R=useCallback(e=>{M(e.id)},[]),D=useCallback(()=>{n(!0)},[]),N=useCallback(()=>{M(null)},[]),K=useCallback(e=>{const t=v[e];t&&M(t.id)},[v]),W=useCallback(e=>{u(e),M(null)},[]),$=useCallback(()=>{u(null),M(null)},[]),G=useCallback(()=>f.reduce((e,t)=>{try{const o=t.getValue();e[t.label]=truncatePayload(o)}catch{e[t.label]=null}return e},{}),[f]),U=useCallback(()=>T.map(e=>({id:e.id,atomLabel:e.atomLabel,timestamp:e.timestamp,prevValue:truncatePayload(e.prevValue),nextValue:truncatePayload(e.nextValue),hasValueChange:e.hasValueChange,changedKeys:e.changedKeys})),[T]),Q=useCallback(()=>v.map(e=>({id:e.id,atomLabel:e.atomLabel,timestamp:e.timestamp,prevValue:truncatePayload(e.prevValue),nextValue:truncatePayload(e.nextValue),hasValueChange:e.hasValueChange,changedKeys:e.changedKeys})),[v]),q=useCallback(e=>{y(t=>{const o=new Set(t);return o.has(e)?o.delete(e):o.add(e),o})},[]),Y=useCallback(e=>{y(t=>new Set([...t,e]))},[]),Z=useCallback(e=>{d(e),u(null),M(null),h(!1),I&&(P(""),C(e=>({...e,searchText:""}))),E(!1)},[I,C]),ee=useCallback(e=>e.id,[]),te=useCallback(({item:e})=>_jsx(JotaiAtomChangeItem,{change:e,onPress:R}),[R]),oe=g.size>0,ae=l?devToolsStorageKeys.modal.root():"buoy-jotai-modal";if(!e)return null;const le=O&&null!==V?_jsx(JotaiAtomDetailFooter,{change:O,changes:v,selectedIndex:V,onIndexChange:K}):null,re=O&&v.length>1?68:0;return _jsxs(_Fragment,{children:[_jsx(JsModal,{visible:e,onClose:t,onMinimize:a,persistenceKey:ae,header:{showToggleButton:!0,customContent:_jsxs(ModalHeader,m?{children:[_jsx(ModalHeader.Navigation,{onBack:()=>h(!1)}),_jsx(ModalHeader.Content,{title:"Filters",centered:!0})]}:O?{children:[_jsx(ModalHeader.Navigation,{onBack:N}),_jsx(ModalHeader.Content,{title:`${O.atomLabel}/${O.category}`,centered:!0})]}:c?{children:[_jsx(ModalHeader.Navigation,{onBack:$}),_jsx(ModalHeader.Content,{title:`${c} History`,centered:!0}),_jsx(ModalHeader.Actions,{children:_jsx(ToolbarCopyButton,{value:Q,disabled:0===v.length,buttonStyle:styles.headerActionButton})})]}:{children:[o&&_jsx(ModalHeader.Navigation,{onBack:o}),_jsx(ModalHeader.Content,{title:"",children:z?_jsxs(View,{style:styles.headerSearchContainer,children:[_jsx(Search,{size:14,color:macOSColors.text.secondary}),_jsx(TextInput,{ref:H,style:styles.headerSearchInput,placeholder:"atoms"===i?"Search atoms...":"Search events...",placeholderTextColor:macOSColors.text.muted,value:I,onChangeText:L,onSubmitEditing:()=>E(!1),onBlur:()=>E(!1),autoCapitalize:"none",autoCorrect:!1,returnKeyType:"search"}),I.length>0&&_jsx(TouchableOpacity,{onPress:()=>{L(""),E(!1)},style:styles.headerSearchClear,children:_jsx(X,{size:14,color:macOSColors.text.secondary})})]}):_jsx(TabSelector,{tabs:[{key:"atoms",label:"Atoms"+(f.length>0?` (${f.length})`:"")},{key:"events",label:"Events"+(T.length>0?` (${T.length})`:"")}],activeTab:i,onTabChange:Z})}),_jsxs(ModalHeader.Actions,{children:[_jsx(TouchableOpacity,{onPress:()=>E(!0),style:styles.headerActionButton,children:_jsx(Search,{size:14,color:macOSColors.text.secondary})}),_jsx(TouchableOpacity,{onPress:()=>h(!0),style:[styles.headerActionButton,oe&&styles.headerActionButtonActive],children:_jsx(Filter,{size:14,color:oe?macOSColors.semantic.debug:macOSColors.text.secondary})}),"atoms"===i&&_jsx(ToolbarCopyButton,{value:G,disabled:0===f.length,buttonStyle:styles.headerActionButton}),"events"===i&&_jsxs(_Fragment,{children:[_jsx(ToolbarCopyButton,{value:U,disabled:0===T.length,buttonStyle:styles.headerActionButton}),_jsx(PowerToggleButton,{isEnabled:_,onToggle:j,accessibilityLabel:"Toggle Jotai atom capture"}),_jsx(ToolbarClearButton,{onPress:S,disabled:0===T.length,buttonStyle:styles.headerActionButton})]})]})]})},onModeChange:F,enablePersistence:!0,initialMode:"bottomSheet",enableGlitchEffects:!0,styles:{},footer:le,footerHeight:re,children:_jsx(View,{style:styles.container,children:m?_jsx(JotaiEventFilterView,{ignoredPatterns:g,onTogglePattern:q,onAddPattern:Y,atoms:p}):O&&null!==V?_jsx(JotaiAtomDetailContent,{change:O,changes:v,selectedIndex:V,onIndexChange:K,disableInternalFooter:!0}):c?v.length>0?_jsx(FlatList,{data:v,renderItem:te,keyExtractor:ee,contentContainerStyle:styles.listContent,showsVerticalScrollIndicator:!0,removeClippedSubviews:!0,initialNumToRender:15,maxToRenderPerBatch:10,windowSize:10,scrollEnabled:!1}):_jsxs(View,{style:styles.emptyState,children:[_jsx(Box,{size:32,color:macOSColors.text.muted}),_jsx(Text,{style:styles.emptyTitle,children:"No history yet"}),_jsxs(Text,{style:styles.emptyText,children:["Changes for ",c," will appear here."]})]}):"atoms"===i?_jsx(JotaiAtomBrowser,{atoms:f,searchQuery:I,onViewHistory:W}):_jsxs(_Fragment,{children:[!_&&_jsxs(View,{style:styles.disabledBanner,children:[_jsx(Power,{size:14,color:macOSColors.semantic.warning}),_jsx(Text,{style:styles.disabledText,children:"Atom capture is disabled"})]}),k&&_jsxs(TouchableOpacity,{style:styles.lockedBanner,onPress:D,activeOpacity:.8,children:[_jsxs(Text,{style:styles.lockedText,children:[B," older"," ",1===B?"change":"changes"," locked"]}),_jsx(View,{style:styles.upgradeBadge,children:_jsx(Text,{style:styles.upgradeBadgeText,children:"UPGRADE"})})]}),w.length>0?_jsx(FlatList,{ref:J,data:w,renderItem:te,keyExtractor:ee,contentContainerStyle:styles.listContent,showsVerticalScrollIndicator:!0,removeClippedSubviews:!0,initialNumToRender:15,maxToRenderPerBatch:10,windowSize:10,scrollEnabled:!1}):_jsx(EventsEmptyState,{isEnabled:_})]})})}),_jsx(ProUpgradeModal,{visible:s,onClose:()=>n(!1),featureName:"Full Atom History"})]})}const styles=StyleSheet.create({container:{flex:1,backgroundColor:macOSColors.background.base},headerSearchContainer:{flexDirection:"row",alignItems:"center",backgroundColor:macOSColors.background.input,borderRadius:10,borderWidth:1,borderColor:macOSColors.border.default,paddingHorizontal:12,paddingVertical:5},headerSearchInput:{flex:1,color:macOSColors.text.primary,fontSize:13,marginLeft:6,paddingVertical:2},headerSearchClear:{marginLeft:6,padding:4},headerActionButton:{width:32,height:32,borderRadius:8,backgroundColor:macOSColors.background.hover,borderWidth:1,borderColor:macOSColors.border.default,alignItems:"center",justifyContent:"center"},headerActionButtonActive:{backgroundColor:macOSColors.semantic.infoBackground},disabledBanner:{flexDirection:"row",alignItems:"center",gap:8,padding:10,marginHorizontal:12,marginTop:8,backgroundColor:macOSColors.semantic.warningBackground,borderRadius:8,borderWidth:1,borderColor:macOSColors.semantic.warning+"20"},disabledText:{color:macOSColors.semantic.warning,fontSize:11,flex:1},listContent:{paddingTop:8,paddingBottom:20},emptyState:{alignItems:"center",paddingVertical:40},emptyTitle:{color:macOSColors.text.primary,fontSize:14,fontWeight:"600",marginTop:12,marginBottom:6},emptyText:{color:macOSColors.text.muted,fontSize:12,textAlign:"center",lineHeight:18},lockedBanner:{flexDirection:"row",alignItems:"center",gap:8,padding:10,marginHorizontal:12,marginTop:8,backgroundColor:buoyColors.primary+"15",borderRadius:8,borderWidth:1,borderColor:buoyColors.primary+"33"},lockedText:{color:buoyColors.primary,fontSize:11,fontWeight:"500",flex:1},upgradeBadge:{backgroundColor:buoyColors.primary,paddingHorizontal:8,paddingVertical:3,borderRadius:4},upgradeBadgeText:{color:"#fff",fontSize:9,fontWeight:"700",letterSpacing:.5}});
@@ -0,0 +1 @@
1
+ "use strict";export{JotaiModal}from"./JotaiModal";export{JotaiIcon,JOTAI_ICON_COLOR}from"./JotaiIcon";export{JotaiAtomChangeItem}from"./JotaiAtomChangeItem";export{JotaiAtomDetailContent,JotaiAtomDetailFooter}from"./JotaiAtomDetailContent";export{JotaiAtomBrowser}from"./JotaiAtomBrowser";export{JotaiEventFilterView}from"./JotaiEventFilterView";
@@ -0,0 +1 @@
1
+ "use strict";import{useState,useEffect,useMemo,useCallback}from"react";import{jotaiStateStore}from"../utils/jotaiStateStore";export function useJotaiAtomChanges(){const[e,t]=useState(()=>jotaiStateStore.getAtomChanges()),[a,o]=useState(()=>jotaiStateStore.getAtoms()),[s,l]=useState({}),[r,n]=useState(()=>jotaiStateStore.getEnabled());useEffect(()=>{const e=jotaiStateStore.subscribe(e=>{t(e)}),a=jotaiStateStore.subscribeToAtoms(e=>{o(e)});return()=>{e(),a()}},[]);const u=useMemo(()=>{let t=e;if(s.searchText){const e=s.searchText.toLowerCase();t=t.filter(t=>t.atomLabel.toLowerCase().includes(e)||t.valuePreview.toLowerCase().includes(e)||t.changedKeys.some(t=>t.toLowerCase().includes(e)))}return s.atomLabels&&s.atomLabels.length>0&&(t=t.filter(e=>s.atomLabels.includes(e.atomLabel))),s.onlyWithChanges&&(t=t.filter(e=>e.hasValueChange)),t},[e,s]),i=useMemo(()=>{const t=e.length,o=e.filter(e=>e.hasValueChange).length;return{totalChanges:t,changesWithValueChange:o,changesWithoutValueChange:t-o,atomCount:a.length}},[e,a]),g=useMemo(()=>jotaiStateStore.getUniqueAtomLabels(),[a]),c=useCallback(()=>{jotaiStateStore.clearAtomChanges()},[]),h=useCallback(()=>{const e=!r;jotaiStateStore.setEnabled(e),n(e)},[r]),S=useCallback(e=>jotaiStateStore.getAtomChangeById(e),[]);return{atomChanges:e,filteredChanges:u,filter:s,setFilter:l,stats:i,atoms:a,clearChanges:c,isEnabled:r,toggleCapture:h,atomLabels:g,getChangeById:S}}
@@ -0,0 +1 @@
1
+ "use strict";export{JotaiModal}from"./components/JotaiModal";export{JotaiIcon,JOTAI_ICON_COLOR}from"./components/JotaiIcon";export{JotaiAtomChangeItem}from"./components/JotaiAtomChangeItem";export{JotaiAtomDetailContent,JotaiAtomDetailFooter}from"./components/JotaiAtomDetailContent";export{JotaiAtomBrowser}from"./components/JotaiAtomBrowser";export{jotaiStateStore}from"./utils/jotaiStateStore";export{watchAtoms,watchDefaultStoreAtoms,isAtomWatched}from"./utils/watchAtoms";export{useJotaiAtomChanges}from"./hooks/useJotaiAtomChanges";
@@ -0,0 +1 @@
1
+ "use strict";
@@ -0,0 +1 @@
1
+ "use strict";const ATOM_COLORS={count:"#10B981",auth:"#8B5CF6",user:"#3B82F6",cart:"#EC4899",app:"#6366F1",ui:"#F59E0B",settings:"#14B8A6",theme:"#06B6D4",nav:"#F97316",form:"#EF4444",modal:"#A855F7",filter:"#84CC16"};function getAtomColor(t){const e=t.toLowerCase();if(ATOM_COLORS[e])return ATOM_COLORS[e];for(const[t,s]of Object.entries(ATOM_COLORS))if(e.includes(t))return s;const s=137*t.split("").reduce((t,e)=>t+e.charCodeAt(0),0)%360,n=.7*(1-Math.abs(1.2-1)),a=n*(1-Math.abs(s/60%2-1)),o=.6-n/2;let r=0,i=0,h=0;s<60?(r=n,i=a):s<120?(r=a,i=n):s<180?(i=n,h=a):s<240?(i=a,h=n):s<300?(r=a,h=n):(r=n,h=a);const l=t=>Math.round(255*(t+o)).toString(16).padStart(2,"0");return`#${l(r)}${l(i)}${l(h)}`}function formatValuePreview(t,e=40){if(void 0===t)return"undefined";if(null===t)return"null";try{if("function"==typeof t)return"(fn)";if("string"==typeof t)return t.length>e?`"${t.slice(0,e-3)}..."`:`"${t}"`;if("number"==typeof t||"boolean"==typeof t)return String(t);if(Array.isArray(t)){if(0===t.length)return"[]";const s=JSON.stringify(t);return s.length>e?`[${t.length} items]`:s}if("object"==typeof t){const s=Object.keys(t);if(0===s.length)return"{}";const n=JSON.stringify(t);return n.length<=e?n:`{ ${s.length} keys }`}return String(t).slice(0,e)}catch{return"[complex]"}}function getValueDiffSummary(t,e){if(t===e)return{summary:"no change",changedKeys:[],changedCount:0};if("object"!=typeof t||"object"!=typeof e||null===t||null===e)return{summary:"changed",changedKeys:[],changedCount:0};const s=Object.keys(t),n=Object.keys(e),a=n.filter(t=>!s.includes(t)),o=s.filter(t=>!n.includes(t)),r=[];for(const a of s)n.includes(a)&&t[a]!==e[a]&&r.push(a);const i=[...a,...o,...r],h=[];a.length>0&&h.push(`+${a.length}`),o.length>0&&h.push(`-${o.length}`),r.length>0&&h.push(`~${r.length}`);const l=i.length;return 0===h.length?{summary:"nested change",changedKeys:[],changedCount:0}:{summary:`${h.join(" ")} ${1===l?"key":"keys"}`,changedKeys:i,changedCount:l}}class JotaiStateStore{atomChanges=[];atoms=new Map;listeners=new Set;atomListeners=new Set;maxChanges=200;idCounter=0;isEnabled=!0;addAtomChange(t){if(!this.isEnabled)return;const{atomLabel:e,prevValue:s,nextValue:n,category:a="write"}=t,o=s!==n,{summary:r,changedKeys:i,changedCount:h}=getValueDiffSummary(s,n),l=formatValuePreview(n),u={id:`${Date.now()}-${++this.idCounter}`,atomLabel:e,timestamp:Date.now(),prevValue:s,nextValue:n,hasValueChange:o,category:a,changedKeys:i,changedKeysCount:h,diffSummary:r,valuePreview:l,isSlowUpdate:!1};this.atomChanges=[u,...this.atomChanges].slice(0,this.maxChanges);const g=this.atoms.get(e);g&&g.changeCount++,this.notifyListeners(),this.notifyAtomListeners()}getAtomChanges(){return[...this.atomChanges]}getAtomChangeById(t){return this.atomChanges.find(e=>e.id===t)}clearAtomChanges(){this.atomChanges=[];for(const t of this.atoms.values())t.changeCount=0;this.notifyListeners(),this.notifyAtomListeners()}registerAtom(t,e){if(this.atoms.has(t))return;const s={label:t,changeCount:0,color:getAtomColor(t),getValue:e};this.atoms.set(t,s),this.notifyAtomListeners()}unregisterAtom(t){this.atoms.delete(t),this.notifyAtomListeners()}getAtoms(){return Array.from(this.atoms.values())}getAtom(t){return this.atoms.get(t)}getAtomColor(t){return this.atoms.get(t)?.color??getAtomColor(t)}filterAtomChanges(t){let e=[...this.atomChanges];if(t.searchText){const s=t.searchText.toLowerCase();e=e.filter(t=>t.atomLabel.toLowerCase().includes(s)||t.valuePreview.toLowerCase().includes(s)||t.changedKeys.some(t=>t.toLowerCase().includes(s)))}return t.atomLabels&&t.atomLabels.length>0&&(e=e.filter(e=>t.atomLabels.includes(e.atomLabel))),t.onlyWithChanges&&(e=e.filter(t=>t.hasValueChange)),e}getStats(){const t=this.atomChanges.length,e=this.atomChanges.filter(t=>t.hasValueChange).length;return{totalChanges:t,changesWithValueChange:e,changesWithoutValueChange:t-e,atomCount:this.atoms.size}}getUniqueAtomLabels(){return Array.from(this.atoms.keys()).sort()}setEnabled(t){this.isEnabled=t}getEnabled(){return this.isEnabled}setMaxChanges(t){this.maxChanges=t,this.atomChanges.length>t&&(this.atomChanges=this.atomChanges.slice(0,t),this.notifyListeners())}subscribe(t){return this.listeners.add(t),()=>this.listeners.delete(t)}subscribeToAtoms(t){return this.atomListeners.add(t),()=>this.atomListeners.delete(t)}notifyListeners(){const t=this.getAtomChanges();this.listeners.forEach(e=>e(t))}notifyAtomListeners(){const t=this.getAtoms();this.atomListeners.forEach(e=>e(t))}}export const jotaiStateStore=new JotaiStateStore;
@@ -0,0 +1 @@
1
+ "use strict";import{jotaiStateStore}from"./jotaiStateStore";export function watchAtoms(t,e,o){const a=!1!==o?.enabled,r=[];for(const[o,i]of Object.entries(e)){const e=i,n=Symbol.for(`@@buoy-jotai/watched/${o}`);if(e[n])continue;let c;e[n]=!0;try{c=t.get(i)}catch{c=void 0}jotaiStateStore.registerAtom(o,()=>{try{return t.get(i)}catch{return}}),a&&jotaiStateStore.addAtomChange({atomLabel:o,prevValue:void 0,nextValue:c,category:"initial"});const u=t.sub(i,()=>{try{const e=t.get(i);jotaiStateStore.addAtomChange({atomLabel:o,prevValue:c,nextValue:e,category:"write"}),c=e}catch{}});r.push(()=>{u(),delete e[n],jotaiStateStore.unregisterAtom(o)})}return()=>r.forEach(t=>t())}export function watchDefaultStoreAtoms(t,e){let o;try{const{getDefaultStore:t}=require("jotai/vanilla");o=t()}catch{try{const{getDefaultStore:t}=require("jotai");o=t()}catch{return console.warn("[@buoy-gg/jotai] Could not find getDefaultStore from jotai. Pass the store explicitly via watchAtoms(store, atoms) instead."),()=>{}}}return watchAtoms(o,t,e)}export function isAtomWatched(t){return void 0!==jotaiStateStore.getAtom(t)}
@@ -0,0 +1 @@
1
+ "use strict";import{JotaiModal}from"./jotai/components/JotaiModal";import{JotaiIcon}from"./jotai/components/JotaiIcon";import{jsx as _jsx}from"react/jsx-runtime";export const jotaiToolPreset={id:"jotai",name:"JOTAI",description:"Jotai atom & state inspector",slot:"both",icon:({size:o})=>_jsx(JotaiIcon,{size:o}),component:JotaiModal,props:{enableSharedModalDimensions:!1}};export function createJotaiTool(o){return{id:o?.id||"jotai",name:o?.name||"JOTAI",description:o?.description||"Jotai atom & state inspector",slot:"both",icon:({size:i})=>_jsx(JotaiIcon,{size:i,color:o?.iconColor}),component:JotaiModal,props:{enableSharedModalDimensions:void 0!==o?.enableSharedModalDimensions&&o.enableSharedModalDimensions}}}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * @buoy-gg/jotai
3
+ *
4
+ * Jotai Atom DevTools for React Native
5
+ *
6
+ * PUBLIC API - Only these exports are supported for external use.
7
+ *
8
+ * @example Recommended setup (one line, pass your atoms)
9
+ * ```tsx
10
+ * import { getDefaultStore } from 'jotai';
11
+ * import { watchAtoms } from '@buoy-gg/jotai';
12
+ * import { countAtom } from './atoms/count';
13
+ * import { authAtom } from './atoms/auth';
14
+ *
15
+ * // One call, anywhere at module scope or in your root layout:
16
+ * watchAtoms(getDefaultStore(), {
17
+ * countAtom,
18
+ * authAtom,
19
+ * });
20
+ * ```
21
+ *
22
+ * @example With a custom store (Provider-based)
23
+ * ```tsx
24
+ * import { createStore } from 'jotai';
25
+ * import { watchAtoms } from '@buoy-gg/jotai';
26
+ *
27
+ * const myStore = createStore();
28
+ *
29
+ * watchAtoms(myStore, { countAtom, authAtom });
30
+ * ```
31
+ */
32
+ export { jotaiToolPreset, createJotaiTool } from "./preset";
33
+ export { watchAtoms } from "./jotai/utils/watchAtoms";
34
+ export { watchDefaultStoreAtoms } from "./jotai/utils/watchAtoms";
35
+ export { isAtomWatched } from "./jotai/utils/watchAtoms";
36
+ export type { JotaiStoreAPI } from "./jotai/utils/watchAtoms";
37
+ export { useJotaiAtomChanges } from "./jotai/hooks/useJotaiAtomChanges";
38
+ export type { UseJotaiAtomChangesResult } from "./jotai/hooks/useJotaiAtomChanges";
39
+ export { JotaiModal } from "./jotai/components/JotaiModal";
40
+ export { JotaiAtomChangeItem } from "./jotai/components/JotaiAtomChangeItem";
41
+ export { JotaiAtomDetailContent, JotaiAtomDetailFooter, } from "./jotai/components/JotaiAtomDetailContent";
42
+ export { JotaiIcon, JOTAI_ICON_COLOR } from "./jotai/components/JotaiIcon";
43
+ export type { JotaiModalProps, JotaiAtomChange, JotaiAtomInfo, JotaiFilter, AtomChangeCategory, WatchAtomsOptions, } from "./jotai/types";
44
+ /** @internal */
45
+ export { jotaiStateStore } from "./jotai/utils/jotaiStateStore";
46
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,15 @@
1
+ /**
2
+ * JotaiAtomBrowser
3
+ *
4
+ * Atoms tab — shows all registered Jotai atoms and their current value.
5
+ * Mirrors ZustandStoreBrowser.tsx from @buoy-gg/zustand.
6
+ */
7
+ import type { JotaiAtomInfo } from "../types";
8
+ interface JotaiAtomBrowserProps {
9
+ atoms: JotaiAtomInfo[];
10
+ searchQuery: string;
11
+ onViewHistory: (atomLabel: string) => void;
12
+ }
13
+ export declare function JotaiAtomBrowser({ atoms, searchQuery, onViewHistory, }: JotaiAtomBrowserProps): import("react").JSX.Element;
14
+ export {};
15
+ //# sourceMappingURL=JotaiAtomBrowser.d.ts.map
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Compact list item for displaying a Jotai atom change
3
+ *
4
+ * Mirrors ZustandStateChangeItem.tsx — uses shared CompactRow for consistent styling
5
+ */
6
+ import type { JotaiAtomChange } from "../types";
7
+ interface JotaiAtomChangeItemProps {
8
+ change: JotaiAtomChange;
9
+ onPress: (change: JotaiAtomChange) => void;
10
+ }
11
+ export declare function JotaiAtomChangeItem({ change, onPress, }: JotaiAtomChangeItemProps): import("react").JSX.Element;
12
+ export {};
13
+ //# sourceMappingURL=JotaiAtomChangeItem.d.ts.map
@@ -0,0 +1,28 @@
1
+ /**
2
+ * JotaiAtomDetailContent
3
+ *
4
+ * Detail view for a Jotai atom change with 3 view modes:
5
+ * - CHANGE: Atom label, timestamp, category, changed keys
6
+ * - VALUE: Full atom value after change
7
+ * - DIFF: Compare prev vs next value
8
+ *
9
+ * Mirrors ZustandStateDetailContent.tsx from @buoy-gg/zustand
10
+ */
11
+ import React from "react";
12
+ import type { JotaiAtomChange } from "../types";
13
+ interface JotaiAtomDetailContentProps {
14
+ change: JotaiAtomChange;
15
+ changes: JotaiAtomChange[];
16
+ selectedIndex: number;
17
+ onIndexChange: (index: number) => void;
18
+ disableInternalFooter?: boolean;
19
+ }
20
+ export declare function JotaiAtomDetailContent({ change, changes, selectedIndex, onIndexChange, disableInternalFooter, }: JotaiAtomDetailContentProps): React.JSX.Element;
21
+ export declare function JotaiAtomDetailFooter({ change, changes, selectedIndex, onIndexChange, }: {
22
+ change: JotaiAtomChange;
23
+ changes: JotaiAtomChange[];
24
+ selectedIndex: number;
25
+ onIndexChange: (index: number) => void;
26
+ }): React.JSX.Element | null;
27
+ export {};
28
+ //# sourceMappingURL=JotaiAtomDetailContent.d.ts.map
@@ -0,0 +1,16 @@
1
+ /**
2
+ * JotaiEventFilterView
3
+ *
4
+ * Filter configuration UI for hiding atoms from the Atoms and Events tabs.
5
+ * Mirrors ZustandEventFilterView.tsx from @buoy-gg/zustand.
6
+ */
7
+ import type { JotaiAtomInfo } from "../types";
8
+ interface JotaiEventFilterViewProps {
9
+ ignoredPatterns: Set<string>;
10
+ onTogglePattern: (pattern: string) => void;
11
+ onAddPattern: (pattern: string) => void;
12
+ atoms: JotaiAtomInfo[];
13
+ }
14
+ export declare function JotaiEventFilterView({ ignoredPatterns, onTogglePattern, onAddPattern, atoms, }: JotaiEventFilterViewProps): import("react").JSX.Element;
15
+ export {};
16
+ //# sourceMappingURL=JotaiEventFilterView.d.ts.map
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Jotai DevTools icon
3
+ */
4
+ declare const JOTAI_ICON_COLOR = "#6C47FF";
5
+ export declare function JotaiIcon({ size, color, }: {
6
+ size: number;
7
+ color?: string;
8
+ }): import("react").JSX.Element;
9
+ export { JOTAI_ICON_COLOR };
10
+ //# sourceMappingURL=JotaiIcon.d.ts.map
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Main Jotai DevTools modal
3
+ *
4
+ * Two tabs mirroring the Zustand DevTools pattern:
5
+ * - Atoms tab: Browse all registered atoms and their current value
6
+ * - Events tab: Live atom change monitoring with diffs
7
+ */
8
+ import type { JotaiModalProps } from "../types";
9
+ export declare function JotaiModal({ visible, onClose, onBack, onMinimize, enableSharedModalDimensions, }: JotaiModalProps): import("react").JSX.Element | null;
10
+ //# sourceMappingURL=JotaiModal.d.ts.map
@@ -0,0 +1,7 @@
1
+ export { JotaiModal } from "./JotaiModal";
2
+ export { JotaiIcon, JOTAI_ICON_COLOR } from "./JotaiIcon";
3
+ export { JotaiAtomChangeItem } from "./JotaiAtomChangeItem";
4
+ export { JotaiAtomDetailContent, JotaiAtomDetailFooter, } from "./JotaiAtomDetailContent";
5
+ export { JotaiAtomBrowser } from "./JotaiAtomBrowser";
6
+ export { JotaiEventFilterView } from "./JotaiEventFilterView";
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Hook for consuming Jotai atom changes from the store
3
+ *
4
+ * Mirrors useZustandStateChanges.ts from @buoy-gg/zustand
5
+ */
6
+ import type { JotaiAtomChange, JotaiAtomInfo, JotaiFilter } from "../types";
7
+ export interface UseJotaiAtomChangesResult {
8
+ /** All captured atom changes */
9
+ atomChanges: JotaiAtomChange[];
10
+ /** Filtered changes based on current filter */
11
+ filteredChanges: JotaiAtomChange[];
12
+ /** Current filter settings */
13
+ filter: JotaiFilter;
14
+ /** Update filter settings */
15
+ setFilter: React.Dispatch<React.SetStateAction<JotaiFilter>>;
16
+ /** Statistics about captured changes */
17
+ stats: {
18
+ totalChanges: number;
19
+ changesWithValueChange: number;
20
+ changesWithoutValueChange: number;
21
+ atomCount: number;
22
+ };
23
+ /** All registered atoms */
24
+ atoms: JotaiAtomInfo[];
25
+ /** Clear all captured changes */
26
+ clearChanges: () => void;
27
+ /** Whether capture is enabled */
28
+ isEnabled: boolean;
29
+ /** Toggle capture on/off */
30
+ toggleCapture: () => void;
31
+ /** Get unique atom labels */
32
+ atomLabels: string[];
33
+ /** Get change by ID */
34
+ getChangeById: (id: string) => JotaiAtomChange | undefined;
35
+ }
36
+ export declare function useJotaiAtomChanges(): UseJotaiAtomChangesResult;
37
+ //# sourceMappingURL=useJotaiAtomChanges.d.ts.map
@@ -0,0 +1,11 @@
1
+ export { JotaiModal } from "./components/JotaiModal";
2
+ export { JotaiIcon, JOTAI_ICON_COLOR } from "./components/JotaiIcon";
3
+ export { JotaiAtomChangeItem } from "./components/JotaiAtomChangeItem";
4
+ export { JotaiAtomDetailContent, JotaiAtomDetailFooter, } from "./components/JotaiAtomDetailContent";
5
+ export { JotaiAtomBrowser } from "./components/JotaiAtomBrowser";
6
+ export { jotaiStateStore } from "./utils/jotaiStateStore";
7
+ export { watchAtoms, watchDefaultStoreAtoms, isAtomWatched, } from "./utils/watchAtoms";
8
+ export type { JotaiStoreAPI } from "./utils/watchAtoms";
9
+ export { useJotaiAtomChanges } from "./hooks/useJotaiAtomChanges";
10
+ export type { JotaiModalProps, JotaiAtomChange, JotaiAtomInfo, JotaiFilter, AtomChangeCategory, WatchAtomsOptions, } from "./types";
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Jotai DevTools types
3
+ */
4
+ /**
5
+ * Atom change category
6
+ */
7
+ export type AtomChangeCategory = "write" | "initial";
8
+ /**
9
+ * Captured Jotai atom change
10
+ */
11
+ export interface JotaiAtomChange {
12
+ id: string;
13
+ atomLabel: string;
14
+ timestamp: number;
15
+ prevValue: unknown;
16
+ nextValue: unknown;
17
+ hasValueChange: boolean;
18
+ category: AtomChangeCategory;
19
+ changedKeys: string[];
20
+ changedKeysCount: number;
21
+ diffSummary: string;
22
+ valuePreview: string;
23
+ isSlowUpdate: boolean;
24
+ }
25
+ /**
26
+ * Tracked Jotai atom metadata
27
+ */
28
+ export interface JotaiAtomInfo {
29
+ label: string;
30
+ changeCount: number;
31
+ color: string;
32
+ getValue: () => unknown;
33
+ }
34
+ /**
35
+ * Filter options
36
+ */
37
+ export interface JotaiFilter {
38
+ searchText?: string;
39
+ atomLabels?: string[];
40
+ onlyWithChanges?: boolean;
41
+ }
42
+ /**
43
+ * Modal props for JotaiModal
44
+ */
45
+ export interface JotaiModalProps {
46
+ visible: boolean;
47
+ onClose: () => void;
48
+ onBack?: () => void;
49
+ onMinimize?: (modalState: unknown) => void;
50
+ enableSharedModalDimensions?: boolean;
51
+ }
52
+ /**
53
+ * Options for watchAtoms
54
+ */
55
+ export interface WatchAtomsOptions {
56
+ /** Enable capture on registration (default: true) */
57
+ enabled?: boolean;
58
+ }
59
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Jotai state store — captures and stores Jotai atom changes
3
+ *
4
+ * Mirrors the architecture of zustandStateStore.ts from @buoy-gg/zustand
5
+ */
6
+ import type { JotaiAtomChange, JotaiAtomInfo, JotaiFilter, AtomChangeCategory } from "../types";
7
+ declare class JotaiStateStore {
8
+ private atomChanges;
9
+ private atoms;
10
+ private listeners;
11
+ private atomListeners;
12
+ private maxChanges;
13
+ private idCounter;
14
+ private isEnabled;
15
+ addAtomChange(params: {
16
+ atomLabel: string;
17
+ prevValue: unknown;
18
+ nextValue: unknown;
19
+ category?: AtomChangeCategory;
20
+ }): void;
21
+ getAtomChanges(): JotaiAtomChange[];
22
+ getAtomChangeById(id: string): JotaiAtomChange | undefined;
23
+ clearAtomChanges(): void;
24
+ registerAtom(label: string, getValue: () => unknown): void;
25
+ unregisterAtom(label: string): void;
26
+ getAtoms(): JotaiAtomInfo[];
27
+ getAtom(label: string): JotaiAtomInfo | undefined;
28
+ getAtomColor(label: string): string;
29
+ filterAtomChanges(filter: JotaiFilter): JotaiAtomChange[];
30
+ getStats(): {
31
+ totalChanges: number;
32
+ changesWithValueChange: number;
33
+ changesWithoutValueChange: number;
34
+ atomCount: number;
35
+ };
36
+ getUniqueAtomLabels(): string[];
37
+ setEnabled(enabled: boolean): void;
38
+ getEnabled(): boolean;
39
+ setMaxChanges(max: number): void;
40
+ subscribe(listener: (changes: JotaiAtomChange[]) => void): () => void;
41
+ subscribeToAtoms(listener: (atoms: JotaiAtomInfo[]) => void): () => void;
42
+ private notifyListeners;
43
+ private notifyAtomListeners;
44
+ }
45
+ export declare const jotaiStateStore: JotaiStateStore;
46
+ export {};
47
+ //# sourceMappingURL=jotaiStateStore.d.ts.map
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Buoy Jotai DevTools — Atom instrumentation
3
+ *
4
+ * watchAtoms() — RECOMMENDED. Pass a Jotai store and a named atom map.
5
+ * Uses store.sub() to observe each atom externally. Never touches atom internals.
6
+ *
7
+ * watchDefaultStoreAtoms() — Convenience wrapper that uses getDefaultStore().
8
+ */
9
+ import type { Atom } from "jotai";
10
+ import type { WatchAtomsOptions } from "../types";
11
+ /** Any Jotai atom — alias for Atom<unknown> for readability */
12
+ type AnyAtom = Atom<unknown>;
13
+ /** Minimal store shape — what Jotai's createStore() / getDefaultStore() returns */
14
+ interface JotaiStoreAPI {
15
+ get: <Value>(atom: Atom<Value>) => Value;
16
+ sub: (atom: AnyAtom, listener: () => void) => () => void;
17
+ }
18
+ /**
19
+ * Watch a set of Jotai atoms for value changes.
20
+ *
21
+ * Pass a Jotai store and an object mapping display names to atoms.
22
+ * Uses store.sub() to observe each atom — never modifies atom internals.
23
+ *
24
+ * @example
25
+ * ```tsx
26
+ * import { getDefaultStore } from 'jotai';
27
+ * import { watchAtoms } from '@buoy-gg/jotai';
28
+ * import { countAtom } from './atoms/count';
29
+ * import { authAtom } from './atoms/auth';
30
+ *
31
+ * watchAtoms(getDefaultStore(), {
32
+ * countAtom,
33
+ * authAtom,
34
+ * });
35
+ * ```
36
+ *
37
+ * @param store - Jotai store (from createStore() or getDefaultStore())
38
+ * @param atoms - Object mapping display labels to Jotai atoms
39
+ * @param options - Optional configuration
40
+ * @returns Cleanup function that removes all subscriptions
41
+ */
42
+ export declare function watchAtoms(store: JotaiStoreAPI, atoms: Record<string, AnyAtom>, options?: WatchAtomsOptions): () => void;
43
+ /**
44
+ * Watch atoms using Jotai's default store (no Provider setup required).
45
+ *
46
+ * Convenience wrapper around watchAtoms() — auto-imports getDefaultStore.
47
+ *
48
+ * @example
49
+ * ```tsx
50
+ * import { watchDefaultStoreAtoms } from '@buoy-gg/jotai';
51
+ * import { countAtom, authAtom } from './atoms';
52
+ *
53
+ * watchDefaultStoreAtoms({ countAtom, authAtom });
54
+ * ```
55
+ */
56
+ export declare function watchDefaultStoreAtoms(atoms: Record<string, AnyAtom>, options?: WatchAtomsOptions): () => void;
57
+ /**
58
+ * Check if an atom label is currently being watched
59
+ */
60
+ export declare function isAtomWatched(label: string): boolean;
61
+ export type { JotaiStoreAPI };
62
+ //# sourceMappingURL=watchAtoms.d.ts.map
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Pre-configured Jotai DevTools preset for FloatingDevTools
3
+ *
4
+ * ZERO-CONFIG: This preset is auto-discovered by FloatingDevTools!
5
+ * Just install @buoy-gg/jotai and call watchAtoms() with your atoms.
6
+ *
7
+ * @example Automatic (recommended)
8
+ * ```tsx
9
+ * import { getDefaultStore } from 'jotai';
10
+ * import { watchAtoms } from '@buoy-gg/jotai';
11
+ * import { countAtom, authAtom } from './atoms';
12
+ *
13
+ * watchAtoms(getDefaultStore(), { countAtom, authAtom });
14
+ *
15
+ * // The Jotai tool appears automatically in FloatingDevTools!
16
+ * <FloatingDevTools />
17
+ * ```
18
+ *
19
+ * @example Manual (only for custom configuration)
20
+ * ```tsx
21
+ * import { createJotaiTool } from '@buoy-gg/jotai';
22
+ *
23
+ * const customJotaiTool = createJotaiTool({
24
+ * name: "ATOMS",
25
+ * iconColor: "#6C47FF",
26
+ * });
27
+ *
28
+ * <FloatingDevTools apps={[customJotaiTool]} />
29
+ * ```
30
+ */
31
+ import { JotaiModal } from "./jotai/components/JotaiModal";
32
+ /**
33
+ * Pre-configured Jotai DevTools preset for FloatingDevTools.
34
+ * Includes:
35
+ * - Live atom change monitoring
36
+ * - Atom value inspection (JSON viewer)
37
+ * - Value diff visualization (tree + split)
38
+ * - Filter by atom label
39
+ * - Changed keys tracking for object atoms
40
+ */
41
+ export declare const jotaiToolPreset: {
42
+ id: string;
43
+ name: string;
44
+ description: string;
45
+ slot: "both";
46
+ icon: ({ size }: {
47
+ size: number;
48
+ }) => import("react").JSX.Element;
49
+ component: typeof JotaiModal;
50
+ props: {
51
+ enableSharedModalDimensions: boolean;
52
+ };
53
+ };
54
+ /**
55
+ * Create a custom Jotai DevTools configuration.
56
+ * Use this if you want to override default settings.
57
+ *
58
+ * @example
59
+ * ```tsx
60
+ * import { createJotaiTool } from '@buoy-gg/jotai';
61
+ *
62
+ * const myJotaiTool = createJotaiTool({
63
+ * name: "ATOMS",
64
+ * iconColor: "#6C47FF",
65
+ * });
66
+ * ```
67
+ */
68
+ export declare function createJotaiTool(options?: {
69
+ /** Tool name (default: "JOTAI") */
70
+ name?: string;
71
+ /** Tool description */
72
+ description?: string;
73
+ /** Custom tool ID (default: "jotai") */
74
+ id?: string;
75
+ /** Icon color */
76
+ iconColor?: string;
77
+ /** Enable shared modal dimensions */
78
+ enableSharedModalDimensions?: boolean;
79
+ }): {
80
+ id: string;
81
+ name: string;
82
+ description: string;
83
+ slot: "both";
84
+ icon: ({ size }: {
85
+ size: number;
86
+ }) => import("react").JSX.Element;
87
+ component: typeof JotaiModal;
88
+ props: {
89
+ enableSharedModalDimensions: boolean;
90
+ };
91
+ };
92
+ //# sourceMappingURL=preset.d.ts.map
package/package.json ADDED
@@ -0,0 +1,81 @@
1
+ {
2
+ "name": "@buoy-gg/jotai",
3
+ "version": "2.1.10",
4
+ "description": "Jotai atom DevTools for React Native",
5
+ "main": "lib/commonjs/index.js",
6
+ "module": "lib/module/index.js",
7
+ "types": "lib/typescript/index.d.ts",
8
+ "react-native": "lib/module/index.js",
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
+ },
24
+ "files": [
25
+ "lib"
26
+ ],
27
+ "sideEffects": false,
28
+ "dependencies": {
29
+ "@buoy-gg/license": "2.1.10",
30
+ "@buoy-gg/shared-ui": "2.1.10"
31
+ },
32
+ "peerDependencies": {
33
+ "jotai": ">=2.0.0",
34
+ "react": "*",
35
+ "react-native": "*"
36
+ },
37
+ "devDependencies": {
38
+ "@types/react": "^19.1.0",
39
+ "@types/react-native": "^0.73.0",
40
+ "jotai": "^2.0.0",
41
+ "typescript": "~5.8.3"
42
+ },
43
+ "react-native-builder-bob": {
44
+ "source": "src",
45
+ "output": "lib",
46
+ "targets": [
47
+ [
48
+ "commonjs",
49
+ {
50
+ "sourceMaps": false
51
+ }
52
+ ],
53
+ [
54
+ "module",
55
+ {
56
+ "sourceMaps": false
57
+ }
58
+ ],
59
+ "typescript"
60
+ ]
61
+ },
62
+ "repository": {
63
+ "type": "git",
64
+ "url": "https://github.com/LovesWorking/react-native-buoy.git",
65
+ "directory": "packages/jotai"
66
+ },
67
+ "bugs": {
68
+ "url": "https://github.com/LovesWorking/react-native-buoy/issues"
69
+ },
70
+ "homepage": "https://github.com/LovesWorking/react-native-buoy/tree/main/packages/jotai#readme",
71
+ "publishConfig": {
72
+ "access": "public",
73
+ "tag": "latest"
74
+ },
75
+ "scripts": {
76
+ "build": "bob build",
77
+ "typecheck": "tsc --noEmit",
78
+ "clean": "rimraf lib",
79
+ "test": "pnpm run typecheck"
80
+ }
81
+ }