@buoy-gg/storage 7.0.77 → 7.0.79

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.
@@ -1,4 +1,4 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.FREE_TIER_KEY_LIMIT=void 0;exports.GameUIStorageBrowser=GameUIStorageBrowser;var _storageLabels=require("../utils/storageLabels");var _react=require("react");var _reactNative=require("react-native");var _sharedUi=require("@buoy-gg/shared-ui");var _StorageKeySection=require("./StorageKeySection");var _StorageKeyDetailScreen=require("./StorageKeyDetailScreen");var _StorageFilterCards=require("./StorageFilterCards");var _useAsyncStorageKeys=require("../hooks/useAsyncStorageKeys");var _AsyncStorageListener=require("../utils/AsyncStorageListener");var _useMMKVKeys=require("../hooks/useMMKVKeys");var _useSecureStoreKeys=require("../hooks/useSecureStoreKeys");var _useMMKVInstances=require("../hooks/useMMKVInstances");var _StorageSaveNotice=require("./StorageSaveNotice");var _StorageActionButtons=require("./StorageActionButtons");var _SelectionActionBar=require("./SelectionActionBar");var _MMKVListener=require("../utils/MMKVListener");var _storageBrowserRefresh=require("../utils/storageBrowserRefresh");var _deleteStorageKeys=require("../utils/deleteStorageKeys");var _setStorageValue=require("../utils/setStorageValue");var _license=require("@buoy-gg/license");var _jsxRuntime=require("react/jsx-runtime");const INSTANCE_COLORS=[_sharedUi.macOSColors.semantic.info,_sharedUi.macOSColors.semantic.success,_sharedUi.macOSColors.semantic.warning,_sharedUi.macOSColors.semantic.debug,"#FF6B9D","#00D9FF"];function getInstanceColor(M){const U=M.split("").reduce((_,P)=>_+P.charCodeAt(0),0);return INSTANCE_COLORS[U%INSTANCE_COLORS.length]}const FREE_TIER_KEY_LIMIT=exports.FREE_TIER_KEY_LIMIT=_sharedUi.TIER_LIMITS["storage.keys"].free;function GameUIStorageBrowser({requiredStorageKeys:M=[],showFilters:U=false,ignoredPatterns:_=new Set(["@react_buoy"]),onTogglePattern:P,onAddPattern:$,searchQuery:m="",storageDataRef:R,eventCountByKey:G,lastWriteByKey:Ze,onViewHistory:A,enabledStorageTypes:I,statusFilter:Y,onStatusFilterChange:J,onStatusCountsChange:X,pinnedKeys:S,onTogglePin:Z,storageTypeFilter:Q,onStorageTypeFilterChange:ee,applySafeAreaInset:fe,detailKey:q=null,onOpenKey:Se,onCloseDetail:te}){const p=(0,_license.useIsPro)();const B=(0,_sharedUi.useLimit)("storage.keys");const re=(0,_sharedUi.useLimit)("storage.mmkvInstances");const[D,T]=(0,_react.useState)(false);(0,_react.useEffect)(()=>{if(D&&p){T(false)}},[D,p]);const[pe,ve]=(0,_react.useState)("all");const L=Y!=null&&J!=null;const y=L?Y:pe;const be=L?J:ve;const[Ce,Te]=(0,_react.useState)("all");const oe=Q!=null&&ee!=null;const d=oe?Q:Ce;const xe=oe?ee:Te;const[l,se]=(0,_react.useState)(null);const we=(0,_react.useRef)(null);const Me=(0,_react.useRef)(0);const ne=(0,_react.useRef)(new Map);const ke=(0,_react.useCallback)((e,t)=>{if(t)ne.current.set(e,t);else ne.current.delete(e)},[]);const[ae,ie]=(0,_react.useState)(0);const[F,z]=(0,_react.useState)(false);const[V,x]=(0,_react.useState)(new Set);const{instances:c}=(0,_useMMKVInstances.useMMKVInstances)(false);const{storageKeys:le,isLoading:Ke,error:_e,refresh:j}=(0,_useAsyncStorageKeys.useAsyncStorageKeys)(M);const Ie=(0,_react.useMemo)(()=>c.map(e=>({instance:e.instance,id:e.id})),[c]);const{storageKeys:O,isLoading:qe,error:Be,refresh:N}=(0,_useMMKVKeys.useMultiMMKVKeys)(Ie,M);const ce=(0,_react.useMemo)(()=>{if(!l){return O}return O.filter(e=>e.instanceId===l)},[O,l]);const{storageKeys:ue,isLoading:Ve,error:je,refresh:de}=(0,_useSecureStoreKeys.useSecureStoreKeys)(M);const a=(0,_react.useMemo)(()=>{return[...le,...ce,...ue].filter(e=>!(0,_sharedUi.isDevToolsStorageKey)(e.key))},[le,ce,ue]);const v=(0,_react.useMemo)(()=>{if(!q)return null;const e=(0,_StorageKeySection.storageRowId)(q);return a.find(t=>(0,_StorageKeySection.storageRowId)(t)===e)??q},[q,a]);const Ne=Ke||qe||Ve;const ge=_e||Be||je;const h=(0,_react.useCallback)(()=>{j();N();de()},[j,N,de]);const w=(0,_react.useCallback)(e=>{return e.instanceId?`${e.storageType}-${e.instanceId}-${e.key}`:`${e.storageType}-${e.key}`},[]);const Ee=(0,_react.useCallback)(()=>{z(e=>{if(e){x(new Set)}return!e})},[]);const Re=(0,_react.useCallback)((e,t)=>{const r=w(e);x(u=>{const s=new Set(u);if(t){s.add(r)}else{s.delete(r)}return s})},[w]);const Ae=(0,_react.useCallback)(()=>{x(new Set);z(false);h()},[h]);const W=(0,_react.useCallback)(e=>{e.forEach(t=>$?.(t.key));x(new Set);z(false)},[$]);const H=(0,_react.useCallback)(async(e,t)=>{if(!p){T(true);throw new Error("Editing storage values is a Pro feature.")}await(0,_setStorageValue.setStorageValue)(e,t,c);h();ie(r=>r+1)},[p,c,h]);const De=(0,_react.useCallback)(e=>{void H(e,JSON.stringify(!e.value)).catch(t=>{_reactNative.Alert.alert("Couldn't save",t instanceof Error?t.message:String(t))})},[H]);const ye=(0,_react.useCallback)((e,t)=>{if(!p){T(true);return}_reactNative.Alert.alert("Delete key",`Delete "${e.key}"? This cannot be undone.`,[{text:"Cancel",style:"cancel"},{text:"Delete",style:"destructive",onPress:async()=>{try{await(0,_deleteStorageKeys.deleteStorageKeys)([e],c.map(r=>({id:r.id,instance:r.instance})));h();t?.()}catch(r){_reactNative.Alert.alert("Error",`Failed to delete key: ${r}`)}}}])},[p,c,h]);const he=(0,_react.useCallback)(e=>(0,_setStorageValue.storageEditBlockedReason)(e,c),[c]);const Le=(0,_react.useMemo)(()=>{const e=a;const t={valid:e.filter(n=>n.status==="required_present"||n.status==="optional_present").length,missing:e.filter(n=>n.status==="required_missing").length,issues:e.filter(n=>n.status==="required_wrong_value"||n.status==="required_wrong_type").length,total:e.length};const r=e.filter(n=>n.storageType==="async");const u=e.filter(n=>n.storageType==="mmkv");const s=e.filter(n=>n.storageType==="secure");return{summary:{valid:t.valid,missing:t.missing,issues:t.issues,total:t.total,timestamp:new Date().toISOString()},asyncStorage:r.reduce((n,i)=>{n[i.key]=i.value;return n},{}),mmkv:u.reduce((n,i)=>{const f=i.instanceId||"default";if(!n[f])n[f]={};n[f][i.key]=i.value;return n},{}),secure:s.reduce((n,i)=>{n[i.key]=i.value;return n},{})}},[a]);(0,_react.useEffect)(()=>{if(R){R.current=a}},[a,R]);(0,_react.useEffect)(()=>{let e;const t=(0,_AsyncStorageListener.addListener)(r=>{clearTimeout(e);e=setTimeout(()=>{j()},100)});return()=>{clearTimeout(e);t()}},[j]);(0,_react.useEffect)(()=>{let e;const t=(0,_storageBrowserRefresh.onStorageBrowserRefresh)(()=>{clearTimeout(e);e=setTimeout(h,100)});return()=>{clearTimeout(e);t()}},[h]);(0,_react.useEffect)(()=>{let e;const t=(0,_MMKVListener.addMMKVListener)(r=>{const u=l===null||r.instanceId===l;if(u){clearTimeout(e);e=setTimeout(()=>{N()},100)}});return()=>{clearTimeout(e);t()}},[N,l]);const k=(0,_react.useMemo)(()=>{const e=a;const t=e.filter(s=>!(0,_sharedUi.isDevToolsStorageKey)(s.key));const r=e.filter(s=>(0,_sharedUi.isDevToolsStorageKey)(s.key));const u={totalCount:e.length,requiredCount:t.filter(s=>s.category==="required").length,missingCount:t.filter(s=>s.status==="required_missing").length,wrongValueCount:t.filter(s=>s.status==="required_wrong_value").length,wrongTypeCount:t.filter(s=>s.status==="required_wrong_type").length,presentRequiredCount:t.filter(s=>s.status==="required_present").length,optionalCount:t.filter(s=>s.category==="optional").length,mmkvCount:e.filter(s=>s.storageType==="mmkv").length,asyncCount:e.filter(s=>s.storageType==="async").length,secureCount:e.filter(s=>s.storageType==="secure").length,devToolsCount:r.length};return u},[a]);const b=(0,_react.useMemo)(()=>{let e=a.filter(o=>!(0,_sharedUi.isDevToolsStorageKey)(o.key));if(d!=="all"){e=e.filter(o=>o.storageType===d)}const t=e.filter(o=>o.status==="required_present"||o.status==="optional_present").length;const r=e.filter(o=>o.status==="required_missing").length;const u=e.filter(o=>o.status==="required_wrong_type"||o.status==="required_wrong_value").length;let s=0;let n=0;let i=0;let f=0;if(y==="all"){s=a.filter(o=>!(0,_sharedUi.isDevToolsStorageKey)(o.key)&&o.storageType==="async"&&(o.status==="required_present"||o.status==="optional_present")).length;n=a.filter(o=>!(0,_sharedUi.isDevToolsStorageKey)(o.key)&&o.storageType==="mmkv"&&(o.status==="required_present"||o.status==="optional_present")).length;i=a.filter(o=>!(0,_sharedUi.isDevToolsStorageKey)(o.key)&&o.storageType==="secure"&&(o.status==="required_present"||o.status==="optional_present")).length;f=s+n+i}else if(y==="missing"){s=a.filter(o=>!(0,_sharedUi.isDevToolsStorageKey)(o.key)&&o.storageType==="async"&&o.status==="required_missing").length;n=a.filter(o=>!(0,_sharedUi.isDevToolsStorageKey)(o.key)&&o.storageType==="mmkv"&&o.status==="required_missing").length;i=a.filter(o=>!(0,_sharedUi.isDevToolsStorageKey)(o.key)&&o.storageType==="secure"&&o.status==="required_missing").length;f=s+n+i}else if(y==="issues"){s=a.filter(o=>!(0,_sharedUi.isDevToolsStorageKey)(o.key)&&o.storageType==="async"&&(o.status==="required_wrong_type"||o.status==="required_wrong_value")).length;n=a.filter(o=>!(0,_sharedUi.isDevToolsStorageKey)(o.key)&&o.storageType==="mmkv"&&(o.status==="required_wrong_type"||o.status==="required_wrong_value")).length;i=a.filter(o=>!(0,_sharedUi.isDevToolsStorageKey)(o.key)&&o.storageType==="secure"&&(o.status==="required_wrong_type"||o.status==="required_wrong_value")).length;f=s+n+i}return{validCount:t,missingCount:r,issuesCount:u,asyncCount:s,mmkvCount:n,secureCount:i,totalCount:f}},[a,y,d]);(0,_react.useEffect)(()=>{X?.({validCount:b.validCount,missingCount:b.missingCount,issuesCount:b.issuesCount})},[X,b.validCount,b.missingCount,b.issuesCount]);const me=(0,_react.useMemo)(()=>{return[...a].sort((e,t)=>{const r={required_missing:1,required_wrong_type:2,required_wrong_value:3,required_present:4,optional_present:5};return(r[e.status]||999)-(r[t.status]||999)})},[a]);const Qe=(0,_react.useMemo)(()=>{return Array.from(new Set(a.map(e=>e.key))).sort()},[a]);const g=(0,_react.useMemo)(()=>{let e=me;if(I&&I.size>0){e=e.filter(t=>I.has(t.storageType))}e=e.filter(t=>{const r=Array.from(_).some(u=>t.key.includes(u));return!r});if(m){const t=m.toLowerCase();e=e.filter(r=>r.key.toLowerCase().includes(t))}switch(y){case"all":e=e.filter(t=>t.status==="required_present"||t.status==="optional_present");break;case"missing":e=e.filter(t=>t.status==="required_missing");break;case"issues":e=e.filter(t=>t.status==="required_wrong_type"||t.status==="required_wrong_value");break}if(d!=="all"){e=e.filter(t=>t.storageType===d)}if(S&&S.size>0){const t=e.filter(u=>S.has(u.key));const r=e.filter(u=>!S.has(u.key));e=[...t,...r]}return e},[me,y,d,_,m,l,I,S]);const C=(0,_react.useMemo)(()=>g.slice(0,B),[g,B]);const E=(0,_react.useMemo)(()=>{return Math.max(0,g.length-B)},[g.length,B]);const Fe=E>0;const et=(0,_react.useMemo)(()=>{const e=g.filter(r=>!(0,_sharedUi.isDevToolsStorageKey)(r.key));const t={totalCount:g.length,requiredCount:e.filter(r=>r.category==="required").length,missingCount:e.filter(r=>r.status==="required_missing").length,wrongValueCount:e.filter(r=>r.status==="required_wrong_value").length,wrongTypeCount:e.filter(r=>r.status==="required_wrong_type").length,presentRequiredCount:e.filter(r=>r.status==="required_present").length,optionalCount:e.filter(r=>r.category==="optional").length,mmkvCount:g.filter(r=>r.storageType==="mmkv").length,asyncCount:g.filter(r=>r.storageType==="async").length,secureCount:g.filter(r=>r.storageType==="secure").length,devToolsCount:g.filter(r=>(0,_sharedUi.isDevToolsStorageKey)(r.key)).length};return t},[g]);const ze=(0,_react.useMemo)(()=>{return C.filter(e=>V.has(w(e)))},[C,V,w]);const Oe=(0,_react.useCallback)(()=>{const e=new Set(C.map(w));x(e)},[C,w]);const We=(0,_react.useCallback)(()=>{x(new Set)},[]);const K=k.requiredCount>0?Math.round(k.presentRequiredCount/k.requiredCount*100):k.totalCount>0?100:0;const He=K>=90?"OPTIMAL":K>=70?"WARNING":"CRITICAL";const Ue=K>=90?_sharedUi.gameUIColors.success:K>=70?_sharedUi.gameUIColors.warning:_sharedUi.gameUIColors.error;if(v){return(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.root,children:(0,_jsxRuntime.jsx)(_StorageKeyDetailScreen.StorageKeyDetailScreen,{storageKey:v,editBlockedReason:he(v),eventCount:G?.[v.key],onSave:e=>H(v,e),onViewHistory:A?()=>A(v.key):void 0,onDeleteKey:e=>ye(e,()=>te?.()),onHideKey:e=>{W([e]);te?.()},isPinned:S?.has(v.key)??false,onTogglePin:Z,applySafeAreaInset:fe})})}if(Ne&&a.length===0){return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.emptyState,children:[(0,_jsxRuntime.jsx)(_sharedUi.Database,{size:48,color:_sharedUi.night.color.textTertiary}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.emptyTitle,children:"Loading storage keys..."})]})}if(ge){return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.emptyState,children:[(0,_jsxRuntime.jsx)(_sharedUi.Database,{size:48,color:_sharedUi.gameUIColors.error}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.emptyTitle,{color:_sharedUi.gameUIColors.error}],children:"Error loading storage"}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.emptySubtitle,children:ge.message})]})}const Pe=(0,_jsxRuntime.jsxs)(_jsxRuntime.Fragment,{children:[d==="mmkv"&&c.length===0&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.emptyMMKVState,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.emptyMMKVTitle,children:"No MMKV Instances Detected"}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.emptyMMKVSubtitle,children:"MMKV instances must be registered with registerMMKVInstance()"}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.emptyMMKVCode,children:`import { registerMMKVInstance } from '@buoy-gg/storage';
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.FREE_TIER_KEY_LIMIT=void 0;exports.GameUIStorageBrowser=GameUIStorageBrowser;var _storageLabels=require("../utils/storageLabels");var _react=require("react");var _reactNative=require("react-native");var _sharedUi=require("@buoy-gg/shared-ui");var _StorageKeySection=require("./StorageKeySection");var _StorageKeyDetailScreen=require("./StorageKeyDetailScreen");var _StorageFilterCards=require("./StorageFilterCards");var _useAsyncStorageKeys=require("../hooks/useAsyncStorageKeys");var _AsyncStorageListener=require("../utils/AsyncStorageListener");var _useMMKVKeys=require("../hooks/useMMKVKeys");var _useSecureStoreKeys=require("../hooks/useSecureStoreKeys");var _useMMKVInstances=require("../hooks/useMMKVInstances");var _StorageSaveNotice=require("./StorageSaveNotice");var _StorageActionButtons=require("./StorageActionButtons");var _SelectionActionBar=require("./SelectionActionBar");var _MMKVListener=require("../utils/MMKVListener");var _storageBrowserRefresh=require("../utils/storageBrowserRefresh");var _deleteStorageKeys=require("../utils/deleteStorageKeys");var _setStorageValue=require("../utils/setStorageValue");var _license=require("@buoy-gg/license");var _jsxRuntime=require("react/jsx-runtime");const INSTANCE_COLORS=[_sharedUi.macOSColors.semantic.info,_sharedUi.macOSColors.semantic.success,_sharedUi.macOSColors.semantic.warning,_sharedUi.macOSColors.semantic.debug,"#FF6B9D","#00D9FF"];function getInstanceColor(k){const P=k.split("").reduce((_,U)=>_+U.charCodeAt(0),0);return INSTANCE_COLORS[P%INSTANCE_COLORS.length]}const FREE_TIER_KEY_LIMIT=exports.FREE_TIER_KEY_LIMIT=_sharedUi.TIER_LIMITS["storage.keys"].free;function GameUIStorageBrowser({requiredStorageKeys:k=[],showFilters:P=false,ignoredPatterns:_=new Set(["@react_buoy"]),onTogglePattern:U,onAddPattern:$,searchQuery:m="",storageDataRef:R,eventCountByKey:G,lastWriteByKey:Ze,onViewHistory:A,enabledStorageTypes:I,statusFilter:Y,onStatusFilterChange:J,onStatusCountsChange:X,pinnedKeys:S,onTogglePin:Z,storageTypeFilter:Q,onStorageTypeFilterChange:ee,applySafeAreaInset:fe,detailKey:q=null,onOpenKey:Se,onCloseDetail:te}){const p=(0,_license.useIsPro)();const B=(0,_sharedUi.useLimit)("storage.keys");const re=(0,_sharedUi.useLimit)("storage.mmkvInstances");const[D,T]=(0,_react.useState)(false);(0,_react.useEffect)(()=>{if(D&&p){T(false)}},[D,p]);const[pe,be]=(0,_react.useState)("all");const L=Y!=null&&J!=null;const y=L?Y:pe;const ve=L?J:be;const[Ce,Te]=(0,_react.useState)("all");const oe=Q!=null&&ee!=null;const d=oe?Q:Ce;const xe=oe?ee:Te;const[l,se]=(0,_react.useState)(null);const we=(0,_react.useRef)(null);const ke=(0,_react.useRef)(0);const ne=(0,_react.useRef)(new Map);const Me=(0,_react.useCallback)((e,t)=>{if(t)ne.current.set(e,t);else ne.current.delete(e)},[]);const[ae,ie]=(0,_react.useState)(0);const[F,z]=(0,_react.useState)(false);const[V,x]=(0,_react.useState)(new Set);const{instances:c}=(0,_useMMKVInstances.useMMKVInstances)(false);const{storageKeys:le,isLoading:Ke,error:_e,refresh:j}=(0,_useAsyncStorageKeys.useAsyncStorageKeys)(k);const Ie=(0,_react.useMemo)(()=>c.map(e=>({instance:e.instance,id:e.id})),[c]);const{storageKeys:O,isLoading:qe,error:Be,refresh:N}=(0,_useMMKVKeys.useMultiMMKVKeys)(Ie,k);const ce=(0,_react.useMemo)(()=>{if(!l){return O}return O.filter(e=>e.instanceId===l)},[O,l]);const{storageKeys:ue,isLoading:Ve,error:je,refresh:de}=(0,_useSecureStoreKeys.useSecureStoreKeys)(k);const a=(0,_react.useMemo)(()=>{return[...le,...ce,...ue].filter(e=>!(0,_sharedUi.isDevToolsStorageKey)(e.key))},[le,ce,ue]);const b=(0,_react.useMemo)(()=>{if(!q)return null;const e=(0,_StorageKeySection.storageRowId)(q);return a.find(t=>(0,_StorageKeySection.storageRowId)(t)===e)??q},[q,a]);const Ne=Ke||qe||Ve;const ge=_e||Be||je;const h=(0,_react.useCallback)(()=>{j();N();de()},[j,N,de]);const w=(0,_react.useCallback)(e=>{return e.instanceId?`${e.storageType}-${e.instanceId}-${e.key}`:`${e.storageType}-${e.key}`},[]);const Ee=(0,_react.useCallback)(()=>{z(e=>{if(e){x(new Set)}return!e})},[]);const Re=(0,_react.useCallback)((e,t)=>{const r=w(e);x(u=>{const s=new Set(u);if(t){s.add(r)}else{s.delete(r)}return s})},[w]);const Ae=(0,_react.useCallback)(()=>{x(new Set);z(false);h()},[h]);const W=(0,_react.useCallback)(e=>{e.forEach(t=>$?.(t.key));x(new Set);z(false)},[$]);const H=(0,_react.useCallback)(async(e,t)=>{if(!p){T(true);throw new Error("Editing storage values is a Pro feature.")}await(0,_setStorageValue.setStorageValue)(e,t,c);h();ie(r=>r+1)},[p,c,h]);const De=(0,_react.useCallback)(e=>{void H(e,JSON.stringify(!e.value)).catch(t=>{_reactNative.Alert.alert("Couldn't save",t instanceof Error?t.message:String(t))})},[H]);const ye=(0,_react.useCallback)((e,t)=>{if(!p){T(true);return}_reactNative.Alert.alert("Delete key",`Delete "${e.key}"? This cannot be undone.`,[{text:"Cancel",style:"cancel"},{text:"Delete",style:"destructive",onPress:async()=>{try{await(0,_deleteStorageKeys.deleteStorageKeys)([e],c.map(r=>({id:r.id,instance:r.instance})));h();t?.()}catch(r){_reactNative.Alert.alert("Error",`Failed to delete key: ${r}`)}}}])},[p,c,h]);const he=(0,_react.useCallback)(e=>(0,_setStorageValue.storageEditBlockedReason)(e,c),[c]);const Le=(0,_react.useMemo)(()=>{const e=a;const t={valid:e.filter(n=>n.status==="required_present"||n.status==="optional_present").length,missing:e.filter(n=>n.status==="required_missing").length,issues:e.filter(n=>n.status==="required_wrong_value"||n.status==="required_wrong_type").length,total:e.length};const r=e.filter(n=>n.storageType==="async");const u=e.filter(n=>n.storageType==="mmkv");const s=e.filter(n=>n.storageType==="secure");return{summary:{valid:t.valid,missing:t.missing,issues:t.issues,total:t.total,timestamp:new Date().toISOString()},asyncStorage:r.reduce((n,i)=>{n[i.key]=i.value;return n},{}),mmkv:u.reduce((n,i)=>{const f=i.instanceId||"default";if(!n[f])n[f]={};n[f][i.key]=i.value;return n},{}),secure:s.reduce((n,i)=>{n[i.key]=i.value;return n},{})}},[a]);(0,_react.useEffect)(()=>{if(R){R.current=a}},[a,R]);(0,_react.useEffect)(()=>{let e;const t=(0,_AsyncStorageListener.addListener)(r=>{clearTimeout(e);e=setTimeout(()=>{j()},100)});return()=>{clearTimeout(e);t()}},[j]);(0,_react.useEffect)(()=>{let e;const t=(0,_storageBrowserRefresh.onStorageBrowserRefresh)(()=>{clearTimeout(e);e=setTimeout(h,100)});return()=>{clearTimeout(e);t()}},[h]);(0,_react.useEffect)(()=>{let e;const t=(0,_MMKVListener.addMMKVListener)(r=>{const u=l===null||r.instanceId===l;if(u){clearTimeout(e);e=setTimeout(()=>{N()},100)}});return()=>{clearTimeout(e);t()}},[N,l]);const M=(0,_react.useMemo)(()=>{const e=a;const t=e.filter(s=>!(0,_sharedUi.isDevToolsStorageKey)(s.key));const r=e.filter(s=>(0,_sharedUi.isDevToolsStorageKey)(s.key));const u={totalCount:e.length,requiredCount:t.filter(s=>s.category==="required").length,missingCount:t.filter(s=>s.status==="required_missing").length,wrongValueCount:t.filter(s=>s.status==="required_wrong_value").length,wrongTypeCount:t.filter(s=>s.status==="required_wrong_type").length,presentRequiredCount:t.filter(s=>s.status==="required_present").length,optionalCount:t.filter(s=>s.category==="optional").length,mmkvCount:e.filter(s=>s.storageType==="mmkv").length,asyncCount:e.filter(s=>s.storageType==="async").length,secureCount:e.filter(s=>s.storageType==="secure").length,devToolsCount:r.length};return u},[a]);const v=(0,_react.useMemo)(()=>{let e=a.filter(o=>!(0,_sharedUi.isDevToolsStorageKey)(o.key));if(d!=="all"){e=e.filter(o=>o.storageType===d)}const t=e.filter(o=>o.status==="required_present"||o.status==="optional_present").length;const r=e.filter(o=>o.status==="required_missing").length;const u=e.filter(o=>o.status==="required_wrong_type"||o.status==="required_wrong_value").length;let s=0;let n=0;let i=0;let f=0;if(y==="all"){s=a.filter(o=>!(0,_sharedUi.isDevToolsStorageKey)(o.key)&&o.storageType==="async"&&(o.status==="required_present"||o.status==="optional_present")).length;n=a.filter(o=>!(0,_sharedUi.isDevToolsStorageKey)(o.key)&&o.storageType==="mmkv"&&(o.status==="required_present"||o.status==="optional_present")).length;i=a.filter(o=>!(0,_sharedUi.isDevToolsStorageKey)(o.key)&&o.storageType==="secure"&&(o.status==="required_present"||o.status==="optional_present")).length;f=s+n+i}else if(y==="missing"){s=a.filter(o=>!(0,_sharedUi.isDevToolsStorageKey)(o.key)&&o.storageType==="async"&&o.status==="required_missing").length;n=a.filter(o=>!(0,_sharedUi.isDevToolsStorageKey)(o.key)&&o.storageType==="mmkv"&&o.status==="required_missing").length;i=a.filter(o=>!(0,_sharedUi.isDevToolsStorageKey)(o.key)&&o.storageType==="secure"&&o.status==="required_missing").length;f=s+n+i}else if(y==="issues"){s=a.filter(o=>!(0,_sharedUi.isDevToolsStorageKey)(o.key)&&o.storageType==="async"&&(o.status==="required_wrong_type"||o.status==="required_wrong_value")).length;n=a.filter(o=>!(0,_sharedUi.isDevToolsStorageKey)(o.key)&&o.storageType==="mmkv"&&(o.status==="required_wrong_type"||o.status==="required_wrong_value")).length;i=a.filter(o=>!(0,_sharedUi.isDevToolsStorageKey)(o.key)&&o.storageType==="secure"&&(o.status==="required_wrong_type"||o.status==="required_wrong_value")).length;f=s+n+i}return{validCount:t,missingCount:r,issuesCount:u,asyncCount:s,mmkvCount:n,secureCount:i,totalCount:f}},[a,y,d]);(0,_react.useEffect)(()=>{X?.({validCount:v.validCount,missingCount:v.missingCount,issuesCount:v.issuesCount})},[X,v.validCount,v.missingCount,v.issuesCount]);const me=(0,_react.useMemo)(()=>{return[...a].sort((e,t)=>{const r={required_missing:1,required_wrong_type:2,required_wrong_value:3,required_present:4,optional_present:5};return(r[e.status]||999)-(r[t.status]||999)})},[a]);const Qe=(0,_react.useMemo)(()=>{return Array.from(new Set(a.map(e=>e.key))).sort()},[a]);const g=(0,_react.useMemo)(()=>{let e=me;if(I&&I.size>0){e=e.filter(t=>I.has(t.storageType))}e=e.filter(t=>{const r=Array.from(_).some(u=>t.key.includes(u));return!r});if(m){const t=m.toLowerCase();e=e.filter(r=>r.key.toLowerCase().includes(t))}switch(y){case"all":e=e.filter(t=>t.status==="required_present"||t.status==="optional_present");break;case"missing":e=e.filter(t=>t.status==="required_missing");break;case"issues":e=e.filter(t=>t.status==="required_wrong_type"||t.status==="required_wrong_value");break}if(d!=="all"){e=e.filter(t=>t.storageType===d)}if(S&&S.size>0){const t=e.filter(u=>S.has(u.key));const r=e.filter(u=>!S.has(u.key));e=[...t,...r]}return e},[me,y,d,_,m,l,I,S]);const C=(0,_react.useMemo)(()=>g.slice(0,B),[g,B]);const E=(0,_react.useMemo)(()=>{return Math.max(0,g.length-B)},[g.length,B]);const Fe=E>0;const et=(0,_react.useMemo)(()=>{const e=g.filter(r=>!(0,_sharedUi.isDevToolsStorageKey)(r.key));const t={totalCount:g.length,requiredCount:e.filter(r=>r.category==="required").length,missingCount:e.filter(r=>r.status==="required_missing").length,wrongValueCount:e.filter(r=>r.status==="required_wrong_value").length,wrongTypeCount:e.filter(r=>r.status==="required_wrong_type").length,presentRequiredCount:e.filter(r=>r.status==="required_present").length,optionalCount:e.filter(r=>r.category==="optional").length,mmkvCount:g.filter(r=>r.storageType==="mmkv").length,asyncCount:g.filter(r=>r.storageType==="async").length,secureCount:g.filter(r=>r.storageType==="secure").length,devToolsCount:g.filter(r=>(0,_sharedUi.isDevToolsStorageKey)(r.key)).length};return t},[g]);const ze=(0,_react.useMemo)(()=>{return C.filter(e=>V.has(w(e)))},[C,V,w]);const Oe=(0,_react.useCallback)(()=>{const e=new Set(C.map(w));x(e)},[C,w]);const We=(0,_react.useCallback)(()=>{x(new Set)},[]);const K=M.requiredCount>0?Math.round(M.presentRequiredCount/M.requiredCount*100):M.totalCount>0?100:0;const He=K>=90?"OPTIMAL":K>=70?"WARNING":"CRITICAL";const Pe=K>=90?_sharedUi.gameUIColors.success:K>=70?_sharedUi.gameUIColors.warning:_sharedUi.gameUIColors.error;if(b){return(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.root,children:(0,_jsxRuntime.jsx)(_StorageKeyDetailScreen.StorageKeyDetailScreen,{storageKey:b,editBlockedReason:he(b),eventCount:G?.[b.key],onSave:e=>H(b,e),onViewHistory:A?()=>A(b.key):void 0,onDeleteKey:e=>ye(e,()=>te?.()),onHideKey:e=>{W([e]);te?.()},isPinned:S?.has(b.key)??false,onTogglePin:Z,applySafeAreaInset:fe})})}if(Ne&&a.length===0){return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.emptyState,children:[(0,_jsxRuntime.jsx)(_sharedUi.Database,{size:48,color:_sharedUi.night.color.textTertiary}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.emptyTitle,children:"Loading storage keys..."})]})}if(ge){return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.emptyState,children:[(0,_jsxRuntime.jsx)(_sharedUi.Database,{size:48,color:_sharedUi.gameUIColors.error}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.emptyTitle,{color:_sharedUi.gameUIColors.error}],children:"Error loading storage"}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.emptySubtitle,children:ge.message})]})}const Ue=(0,_jsxRuntime.jsxs)(_jsxRuntime.Fragment,{children:[d==="mmkv"&&c.length===0&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.emptyMMKVState,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.emptyMMKVTitle,children:"No MMKV Instances Detected"}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.emptyMMKVSubtitle,children:"MMKV instances must be registered with registerMMKVInstance()"}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.emptyMMKVCode,children:`import { registerMMKVInstance } from '@buoy-gg/storage';
2
2
 
3
3
  const storage = createMMKV();
4
- registerMMKVInstance('mmkv.default', storage);`})]}),d==="mmkv"&&c.length>0&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.instanceNavbar,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.instanceNavbarHeader,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.instanceNavbarLabel,children:"INSTANCES"}),c.length>re&&(0,_jsxRuntime.jsx)(_sharedUi.ProBadge,{style:{transform:[{scale:.85}]}})]}),(0,_jsxRuntime.jsxs)(_reactNative.ScrollView,{horizontal:true,showsHorizontalScrollIndicator:false,contentContainerStyle:styles.instanceNavbarScroll,children:[(p||c.length===1)&&(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{onPress:()=>se(null),testID:"buoy-storage-instance-all",accessibilityRole:"button",accessibilityLabel:`All ${_storageLabels.storageLabels.mmkv} instances`,style:[styles.instanceNavbarButton,l===null&&styles.instanceNavbarButtonActive],children:[(0,_jsxRuntime.jsx)(_sharedUi.HardDrive,{size:12,color:l===null?_sharedUi.night.color.text:_sharedUi.night.color.textSecondary}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.instanceNavbarButtonText,l===null&&styles.instanceNavbarButtonTextActive],children:"All"}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.instanceNavbarBadge,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.instanceNavbarBadgeText,children:c.reduce((e,t)=>e+t.keyCount,0)})})]}),c.map((e,t)=>{const r=t>=re;return(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{testID:`buoy-storage-instance-${e.id}`,accessibilityRole:"button",accessibilityLabel:`MMKV instance ${e.id}`,onPress:()=>{if(r){T(true)}else{se(e.id)}},style:[styles.instanceNavbarButton,e.id===l&&styles.instanceNavbarButtonActive,{borderColor:r?_sharedUi.night.color.border:getInstanceColor(e.id)+"40",backgroundColor:e.id===l?getInstanceColor(e.id)+"20":_sharedUi.night.color.surfaceElevated,opacity:r?.5:1}],children:[(0,_jsxRuntime.jsx)(_sharedUi.HardDrive,{size:12,color:e.id===l?getInstanceColor(e.id):_sharedUi.night.color.textSecondary}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.instanceNavbarButtonText,e.id===l&&{color:getInstanceColor(e.id),fontWeight:"700"}],children:e.id}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.instanceNavbarBadge,e.id===l&&{backgroundColor:getInstanceColor(e.id)+"30"}],children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.instanceNavbarBadgeText,e.id===l&&{color:getInstanceColor(e.id)}],children:e.keyCount})})]},e.id)})]})]})]});const $e=(0,_jsxRuntime.jsx)(_StorageActionButtons.StorageActionButtons,{copyValue:Le,mmkvInstances:c.map(e=>({id:e.id,instance:e.instance})),activeStorageType:d,onClearComplete:h,isSelectMode:F,onToggleSelectMode:Ee,selectedCount:V.size});const Ge=F?(0,_jsxRuntime.jsx)(_SelectionActionBar.SelectionActionBar,{selectedKeys:ze,mmkvInstances:c.map(e=>({id:e.id,instance:e.instance})),onDeleteComplete:Ae,onHideKeys:W,onSelectAll:Oe,onClearSelection:We,totalVisibleKeys:C.length}):null;const Ye=Fe?(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{style:styles.limitBanner,onPress:()=>T(true),activeOpacity:.8,testID:"buoy-storage-locked-banner",accessibilityRole:"button",children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.limitBannerContent,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.limitBannerLeft,children:[(0,_jsxRuntime.jsx)(_sharedUi.Zap,{size:16,color:_sharedUi.night.color.accent}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.limitBannerText,children:m?`${E} matching ${E===1?"key":"keys"} in locked storage`:`${E} keys locked`})]}),(0,_jsxRuntime.jsx)(_sharedUi.ProBadge,{})]}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.limitBannerSubtext,children:m?"Upgrade to Pro to search your full storage":"Upgrade to Pro to unlock full storage access"})]}):null;const Je=(()=>{const e=a.some(r=>!(0,_sharedUi.isDevToolsStorageKey)(r.key));let t;if(m||!e){t=(0,_sharedUi.resolveListEmptyState)({subject:"keys",verb:"registered",search:m,total:e?1:0,waiting:{otto:"empty",title:"No storage keys",message:"Nothing is registered for this tool to read."}});if(m&&e){t={...t,message:"No keys match. Clear the search to see them."}}}else if(y==="missing"){t={otto:"thumbsup",title:"No missing keys",message:"All required keys are present"}}else if(y==="issues"){t={otto:"cool",title:"No issues found",message:"All storage keys are correctly configured"}}else{t={otto:"broken",title:"No valid keys found",message:"All keys have issues or are missing"}}return(0,_jsxRuntime.jsx)(_sharedUi.ToolEmptyState,{...t,testID:"buoy-storage-keys-empty"})})();const Xe=(0,_jsxRuntime.jsx)(_sharedUi.ProUpgradeModal,{visible:D,onClose:()=>T(false),featureName:"Storage Keys"});return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.root,children:[ae>0?(0,_jsxRuntime.jsx)(_StorageSaveNotice.StorageSaveNotice,{onDone:()=>ie(0)},ae):null,(0,_jsxRuntime.jsxs)(_reactNative.ScrollView,{testID:"buoy-storage-scroll",ref:we,onScroll:e=>{Me.current=e.nativeEvent.contentOffset.y},scrollEventThrottle:32,style:styles.scrollContainer,contentContainerStyle:styles.container,showsVerticalScrollIndicator:false,children:[(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.backgroundGrid}),(0,_jsxRuntime.jsx)(_StorageFilterCards.StorageFilterCards,{stats:k,tabStats:b,healthPercentage:K,healthStatus:He,healthColor:Ue,activeFilter:y,onFilterChange:be,activeStorageType:d,onStorageTypeChange:xe,showStatus:!L}),Pe,g.length>0?(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.keysSection,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.sectionHeader,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.sectionHeaderLeft,children:[(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.sectionTitle,children:[y==="all"?"KEYS":y==="missing"?"MISSING KEYS":"ISSUES TO FIX",d!=="all"&&` (${d.toUpperCase()})`]}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.countBadge,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.countText,children:C.length})})]}),$e]}),Ge,(0,_jsxRuntime.jsx)(_StorageKeySection.StorageKeySection,{title:"",count:-1,keys:C,emptyMessage:"",isSelectMode:F,selectedKeys:V,onSelectionChange:Re,eventCountByKey:G,onViewHistory:A,onHideKey:e=>W([e]),onToggleKey:De,onDeleteKey:ye,editBlockedFor:he,pinnedKeys:S,onTogglePin:Z,onRowRef:ke,onOpenKey:Se}),Ye]}):Je,(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.techFooter,children:"ASYNC STORAGE | MMKV | SECURE STORAGE BACKENDS"}),Xe]})]})}const styles=_reactNative.StyleSheet.create({root:{flex:1,minHeight:0},editorOverlay:{..._sharedUi.absoluteFill,zIndex:10},scrollContainer:{flex:1,backgroundColor:"transparent"},container:{padding:12,paddingBottom:120},backgroundGrid:{..._sharedUi.absoluteFill,opacity:.006,backgroundColor:_sharedUi.gameUIColors.info},techFooter:{fontSize:8,color:_sharedUi.night.color.textTertiary,fontFamily:_sharedUi.monoFont,textAlign:"center",marginTop:20,letterSpacing:1,opacity:.5},keysSection:{marginTop:8,backgroundColor:_sharedUi.night.color.bg,borderRadius:12,padding:12,borderWidth:1,borderColor:_sharedUi.night.color.border},sectionHeader:{flexDirection:"row",justifyContent:"space-between",alignItems:"center",marginBottom:10,paddingBottom:6,borderBottomWidth:1,borderBottomColor:_sharedUi.night.color.separator},sectionHeaderLeft:{flexDirection:"row",alignItems:"center",gap:8},sectionTitle:{fontSize:12,fontWeight:"600",color:_sharedUi.night.color.textSecondary,letterSpacing:.4,textTransform:"uppercase"},countBadge:{backgroundColor:_sharedUi.night.color.surfaceElevated,paddingHorizontal:8,paddingVertical:3,borderRadius:6,borderWidth:1,borderColor:_sharedUi.night.color.border},countText:{fontSize:11,fontWeight:"600",color:_sharedUi.night.color.text,fontFamily:_sharedUi.monoFont},emptyState:{alignItems:"center",justifyContent:"center",paddingVertical:48},emptyTitle:{fontSize:16,fontWeight:"600",color:_sharedUi.night.color.text,marginTop:12,marginBottom:8},emptySubtitle:{fontSize:13,color:_sharedUi.night.color.textSecondary,textAlign:"center"},emptyMMKVState:{backgroundColor:_sharedUi.night.color.surface,borderRadius:12,padding:20,borderWidth:1,borderColor:_sharedUi.night.color.border,marginTop:8,alignItems:"center"},emptyMMKVTitle:{fontSize:14,fontWeight:"600",color:_sharedUi.night.color.text,marginBottom:6},emptyMMKVSubtitle:{fontSize:12,color:_sharedUi.night.color.textSecondary,textAlign:"center",marginBottom:12},emptyMMKVCode:{fontSize:10,fontFamily:_sharedUi.monoFont,color:_sharedUi.night.color.accent,backgroundColor:_sharedUi.night.color.bg,padding:12,borderRadius:8,borderWidth:1,borderColor:_sharedUi.night.color.border,alignSelf:"stretch"},instanceNavbar:{marginTop:12,marginBottom:8,backgroundColor:_sharedUi.night.color.surface,borderRadius:10,borderWidth:1,borderColor:_sharedUi.night.color.border,padding:10,shadowColor:"#000",shadowOpacity:.08,shadowRadius:6,shadowOffset:{width:0,height:2}},instanceNavbarHeader:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",marginBottom:8,paddingLeft:2},instanceNavbarLabel:{fontSize:9,fontWeight:"700",color:_sharedUi.night.color.textTertiary,textTransform:"uppercase",letterSpacing:1},instanceNavbarScroll:{gap:8,paddingRight:8},instanceNavbarButton:{flexDirection:"row",alignItems:"center",gap:6,paddingHorizontal:12,paddingVertical:8,backgroundColor:_sharedUi.night.color.surfaceElevated,borderRadius:8,borderWidth:1,borderColor:_sharedUi.night.color.border,minWidth:90},instanceNavbarButtonActive:{borderWidth:1.5,shadowColor:"#000",shadowOpacity:.1,shadowRadius:4,shadowOffset:{width:0,height:1}},instanceNavbarButtonText:{fontSize:11,fontWeight:"600",color:_sharedUi.night.color.textSecondary,fontFamily:_sharedUi.monoFont,flex:1},instanceNavbarButtonTextActive:{fontWeight:"700",color:_sharedUi.night.color.text},instanceNavbarBadge:{backgroundColor:_sharedUi.night.color.bg,paddingHorizontal:6,paddingVertical:2,borderRadius:6,minWidth:24,alignItems:"center"},instanceNavbarBadgeText:{fontSize:10,fontWeight:"700",color:_sharedUi.night.color.textSecondary,fontFamily:_sharedUi.monoFont},clearSearchButton:{marginTop:16,paddingHorizontal:16,paddingVertical:8,backgroundColor:_sharedUi.night.color.surfaceElevated,borderRadius:6,borderWidth:1,borderColor:_sharedUi.night.color.border},clearSearchText:{fontSize:13,color:_sharedUi.night.color.text,fontWeight:"500"},limitBanner:{backgroundColor:_sharedUi.night.color.surface,borderRadius:10,borderWidth:1,borderColor:_sharedUi.night.color.accentBorderStrong,padding:12,marginTop:12},limitBannerContent:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",marginBottom:4},limitBannerLeft:{flexDirection:"row",alignItems:"center",gap:8},limitBannerText:{color:_sharedUi.night.color.text,fontSize:13,fontWeight:"600"},limitBannerSubtext:{color:_sharedUi.night.color.textTertiary,fontSize:11}});
4
+ registerMMKVInstance('mmkv.default', storage);`})]}),d==="mmkv"&&c.length>0&&(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.instanceNavbar,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.instanceNavbarHeader,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.instanceNavbarLabel,children:"INSTANCES"}),c.length>re&&(0,_jsxRuntime.jsx)(_sharedUi.ProBadge,{style:{transform:[{scale:.85}]}})]}),(0,_jsxRuntime.jsxs)(_reactNative.ScrollView,{horizontal:true,showsHorizontalScrollIndicator:false,contentContainerStyle:styles.instanceNavbarScroll,children:[(p||c.length===1)&&(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{onPress:()=>se(null),testID:"buoy-storage-instance-all",accessibilityRole:"button",accessibilityLabel:`All ${_storageLabels.storageLabels.mmkv} instances`,style:[styles.instanceNavbarButton,l===null&&styles.instanceNavbarButtonActive],children:[(0,_jsxRuntime.jsx)(_sharedUi.HardDrive,{size:12,color:l===null?_sharedUi.night.color.text:_sharedUi.night.color.textSecondary}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.instanceNavbarButtonText,l===null&&styles.instanceNavbarButtonTextActive],children:"All"}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.instanceNavbarBadge,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.instanceNavbarBadgeText,children:c.reduce((e,t)=>e+t.keyCount,0)})})]}),c.map((e,t)=>{const r=t>=re;return(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{testID:`buoy-storage-instance-${e.id}`,accessibilityRole:"button",accessibilityLabel:`MMKV instance ${e.id}`,onPress:()=>{if(r){T(true)}else{se(e.id)}},style:[styles.instanceNavbarButton,e.id===l&&styles.instanceNavbarButtonActive,{borderColor:r?_sharedUi.night.color.border:getInstanceColor(e.id)+"40",backgroundColor:e.id===l?getInstanceColor(e.id)+"20":_sharedUi.night.color.surfaceElevated,opacity:r?.5:1}],children:[(0,_jsxRuntime.jsx)(_sharedUi.HardDrive,{size:12,color:e.id===l?getInstanceColor(e.id):_sharedUi.night.color.textSecondary}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.instanceNavbarButtonText,e.id===l&&{color:getInstanceColor(e.id),fontWeight:"700"}],children:e.id}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.instanceNavbarBadge,e.id===l&&{backgroundColor:getInstanceColor(e.id)+"30"}],children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.instanceNavbarBadgeText,e.id===l&&{color:getInstanceColor(e.id)}],children:e.keyCount})})]},e.id)})]})]})]});const $e=(0,_jsxRuntime.jsx)(_StorageActionButtons.StorageActionButtons,{copyValue:Le,mmkvInstances:c.map(e=>({id:e.id,instance:e.instance})),activeStorageType:d,onClearComplete:h,isSelectMode:F,onToggleSelectMode:Ee,selectedCount:V.size});const Ge=F?(0,_jsxRuntime.jsx)(_SelectionActionBar.SelectionActionBar,{selectedKeys:ze,mmkvInstances:c.map(e=>({id:e.id,instance:e.instance})),onDeleteComplete:Ae,onHideKeys:W,onSelectAll:Oe,onClearSelection:We,totalVisibleKeys:C.length}):null;const Ye=Fe?(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{style:styles.limitBanner,onPress:()=>T(true),activeOpacity:.8,testID:"buoy-storage-locked-banner",accessibilityRole:"button",children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.limitBannerContent,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.limitBannerLeft,children:[(0,_jsxRuntime.jsx)(_sharedUi.Zap,{size:16,color:_sharedUi.night.color.accent}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.limitBannerText,children:m?`${E} matching ${E===1?"key":"keys"} in locked storage`:`${E} keys locked`})]}),(0,_jsxRuntime.jsx)(_sharedUi.ProBadge,{})]}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.limitBannerSubtext,children:m?"Upgrade to Pro to search your full storage":"Upgrade to Pro to unlock full storage access"})]}):null;const Je=(()=>{const e=a.some(r=>!(0,_sharedUi.isDevToolsStorageKey)(r.key));let t;if(m||!e){t=(0,_sharedUi.resolveListEmptyState)({subject:"keys",verb:"registered",search:m,total:e?1:0,waiting:{otto:"empty",title:"No storage keys",message:"Nothing is registered for this tool to read."}});if(m&&e){t={...t,message:"No keys match. Clear the search to see them."}}}else if(y==="missing"){t={otto:"thumbsup",title:"No missing keys",message:"All required keys are present"}}else if(y==="issues"){t={otto:"cool",title:"No issues found",message:"All storage keys are correctly configured"}}else{t={otto:"broken",title:"No valid keys found",message:"All keys have issues or are missing"}}return(0,_jsxRuntime.jsx)(_sharedUi.ToolEmptyState,{...t,testID:"buoy-storage-keys-empty"})})();const Xe=(0,_jsxRuntime.jsx)(_sharedUi.ProUpgradeModal,{visible:D,onClose:()=>T(false),featureName:"Storage Keys"});return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.root,children:[ae>0?(0,_jsxRuntime.jsx)(_StorageSaveNotice.StorageSaveNotice,{onDone:()=>ie(0)},ae):null,(0,_jsxRuntime.jsxs)(_reactNative.ScrollView,{keyboardShouldPersistTaps:"handled",testID:"buoy-storage-scroll",ref:we,onScroll:e=>{ke.current=e.nativeEvent.contentOffset.y},scrollEventThrottle:32,style:styles.scrollContainer,contentContainerStyle:styles.container,showsVerticalScrollIndicator:false,children:[(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.backgroundGrid}),(0,_jsxRuntime.jsx)(_StorageFilterCards.StorageFilterCards,{stats:M,tabStats:v,healthPercentage:K,healthStatus:He,healthColor:Pe,activeFilter:y,onFilterChange:ve,activeStorageType:d,onStorageTypeChange:xe,showStatus:!L}),Ue,g.length>0?(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.keysSection,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.sectionHeader,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.sectionHeaderLeft,children:[(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.sectionTitle,children:[y==="all"?"KEYS":y==="missing"?"MISSING KEYS":"ISSUES TO FIX",d!=="all"&&` (${d.toUpperCase()})`]}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.countBadge,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.countText,children:C.length})})]}),$e]}),Ge,(0,_jsxRuntime.jsx)(_StorageKeySection.StorageKeySection,{title:"",count:-1,keys:C,emptyMessage:"",isSelectMode:F,selectedKeys:V,onSelectionChange:Re,eventCountByKey:G,onViewHistory:A,onHideKey:e=>W([e]),onToggleKey:De,onDeleteKey:ye,editBlockedFor:he,pinnedKeys:S,onTogglePin:Z,onRowRef:Me,onOpenKey:Se}),Ye]}):Je,(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.techFooter,children:"ASYNC STORAGE | MMKV | SECURE STORAGE BACKENDS"}),Xe]})]})}const styles=_reactNative.StyleSheet.create({root:{flex:1,minHeight:0},editorOverlay:{..._sharedUi.absoluteFill,zIndex:10},scrollContainer:{flex:1,backgroundColor:"transparent"},container:{padding:12,paddingBottom:120},backgroundGrid:{..._sharedUi.absoluteFill,opacity:.006,backgroundColor:_sharedUi.gameUIColors.info},techFooter:{fontSize:8,color:_sharedUi.night.color.textTertiary,fontFamily:_sharedUi.monoFont,textAlign:"center",marginTop:20,letterSpacing:1,opacity:.5},keysSection:{marginTop:8,backgroundColor:_sharedUi.night.color.bg,borderRadius:12,padding:12,borderWidth:1,borderColor:_sharedUi.night.color.border},sectionHeader:{flexDirection:"row",justifyContent:"space-between",alignItems:"center",marginBottom:10,paddingBottom:6,borderBottomWidth:1,borderBottomColor:_sharedUi.night.color.separator},sectionHeaderLeft:{flexDirection:"row",alignItems:"center",gap:8},sectionTitle:{fontSize:12,fontWeight:"600",color:_sharedUi.night.color.textSecondary,letterSpacing:.4,textTransform:"uppercase"},countBadge:{backgroundColor:_sharedUi.night.color.surfaceElevated,paddingHorizontal:8,paddingVertical:3,borderRadius:6,borderWidth:1,borderColor:_sharedUi.night.color.border},countText:{fontSize:11,fontWeight:"600",color:_sharedUi.night.color.text,fontFamily:_sharedUi.monoFont},emptyState:{alignItems:"center",justifyContent:"center",paddingVertical:48},emptyTitle:{fontSize:16,fontWeight:"600",color:_sharedUi.night.color.text,marginTop:12,marginBottom:8},emptySubtitle:{fontSize:13,color:_sharedUi.night.color.textSecondary,textAlign:"center"},emptyMMKVState:{backgroundColor:_sharedUi.night.color.surface,borderRadius:12,padding:20,borderWidth:1,borderColor:_sharedUi.night.color.border,marginTop:8,alignItems:"center"},emptyMMKVTitle:{fontSize:14,fontWeight:"600",color:_sharedUi.night.color.text,marginBottom:6},emptyMMKVSubtitle:{fontSize:12,color:_sharedUi.night.color.textSecondary,textAlign:"center",marginBottom:12},emptyMMKVCode:{fontSize:10,fontFamily:_sharedUi.monoFont,color:_sharedUi.night.color.accent,backgroundColor:_sharedUi.night.color.bg,padding:12,borderRadius:8,borderWidth:1,borderColor:_sharedUi.night.color.border,alignSelf:"stretch"},instanceNavbar:{marginTop:12,marginBottom:8,backgroundColor:_sharedUi.night.color.surface,borderRadius:10,borderWidth:1,borderColor:_sharedUi.night.color.border,padding:10,shadowColor:"#000",shadowOpacity:.08,shadowRadius:6,shadowOffset:{width:0,height:2}},instanceNavbarHeader:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",marginBottom:8,paddingLeft:2},instanceNavbarLabel:{fontSize:9,fontWeight:"700",color:_sharedUi.night.color.textTertiary,textTransform:"uppercase",letterSpacing:1},instanceNavbarScroll:{gap:8,paddingRight:8},instanceNavbarButton:{flexDirection:"row",alignItems:"center",gap:6,paddingHorizontal:12,paddingVertical:8,backgroundColor:_sharedUi.night.color.surfaceElevated,borderRadius:8,borderWidth:1,borderColor:_sharedUi.night.color.border,minWidth:90},instanceNavbarButtonActive:{borderWidth:1.5,shadowColor:"#000",shadowOpacity:.1,shadowRadius:4,shadowOffset:{width:0,height:1}},instanceNavbarButtonText:{fontSize:11,fontWeight:"600",color:_sharedUi.night.color.textSecondary,fontFamily:_sharedUi.monoFont,flex:1},instanceNavbarButtonTextActive:{fontWeight:"700",color:_sharedUi.night.color.text},instanceNavbarBadge:{backgroundColor:_sharedUi.night.color.bg,paddingHorizontal:6,paddingVertical:2,borderRadius:6,minWidth:24,alignItems:"center"},instanceNavbarBadgeText:{fontSize:10,fontWeight:"700",color:_sharedUi.night.color.textSecondary,fontFamily:_sharedUi.monoFont},clearSearchButton:{marginTop:16,paddingHorizontal:16,paddingVertical:8,backgroundColor:_sharedUi.night.color.surfaceElevated,borderRadius:6,borderWidth:1,borderColor:_sharedUi.night.color.border},clearSearchText:{fontSize:13,color:_sharedUi.night.color.text,fontWeight:"500"},limitBanner:{backgroundColor:_sharedUi.night.color.surface,borderRadius:10,borderWidth:1,borderColor:_sharedUi.night.color.accentBorderStrong,padding:12,marginTop:12},limitBannerContent:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",marginBottom:4},limitBannerLeft:{flexDirection:"row",alignItems:"center",gap:8},limitBannerText:{color:_sharedUi.night.color.text,fontSize:13,fontWeight:"600"},limitBannerSubtext:{color:_sharedUi.night.color.textTertiary,fontSize:11}});
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.MMKVInstanceSelector=MMKVInstanceSelector;var _storageLabels=require("../utils/storageLabels");var _react=require("react");var _reactNative=require("react-native");var _sharedUi=require("@buoy-gg/shared-ui");var _useMMKVInstances=require("../hooks/useMMKVInstances");var _mmkvAvailability=require("../utils/mmkvAvailability");var _jsxRuntime=require("react/jsx-runtime");function MMKVInstanceSelector({selectedInstanceId:t,onSelectInstance:r,showRefreshButton:n=true}){const[c,o]=(0,_react.useState)(false);const{instances:i,instanceCount:a,refresh:s}=(0,_useMMKVInstances.useMMKVInstances)(false);const l=i.find(e=>e.id===t);const d=e=>{r(e);o(false)};if(!(0,_mmkvAvailability.isMMKVAvailable)()){return(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.container,children:(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.unavailableState,children:[(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.unavailableTitle,children:[_storageLabels.storageLabels.mmkv," Not Available"]}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.unavailableDescription,children:(0,_mmkvAvailability.getMMKVUnavailableMessage)()})]})})}if(a===0){return(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.container,children:(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.emptyState,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.emptyStateTitle,children:"No MMKV Instances Registered"}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.emptyStateDescription,children:"Register MMKV instances using registerMMKVInstance() to monitor them in dev tools."}),n&&(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:styles.refreshButton,onPress:s,activeOpacity:.7,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.refreshButtonText,children:"\u21BB Refresh"})})]})})}return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.container,children:[(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{style:styles.selectorButton,onPress:()=>o(true),activeOpacity:.7,children:[(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.selectorContent,children:l?(0,_jsxRuntime.jsx)(InstanceRow,{instance:l,isSelected:true}):(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.placeholderText,children:"Select MMKV Instance"})}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.dropdownArrow,children:"\u25BC"})]}),(0,_jsxRuntime.jsx)(_reactNative.Modal,{visible:c,transparent:true,animationType:"fade",onRequestClose:()=>o(false),children:(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:styles.modalOverlay,activeOpacity:1,onPress:()=>o(false),children:(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.dropdownContainer,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.dropdownHeader,children:[(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.dropdownTitle,children:["Select MMKV Instance (",a,")"]}),n&&(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:styles.headerRefreshButton,onPress:s,activeOpacity:.7,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.headerRefreshText,children:"\u21BB"})})]}),(0,_jsxRuntime.jsx)(_reactNative.ScrollView,{style:styles.dropdownList,children:i.map(e=>(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:[styles.dropdownItem,e.id===t&&styles.dropdownItemSelected],onPress:()=>d(e.id),activeOpacity:.7,children:(0,_jsxRuntime.jsx)(InstanceRow,{instance:e,isSelected:e.id===t})},e.id))})]})})})]})}function InstanceRow({instance:t,isSelected:r}){return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.instanceRow,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.instanceLeft,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.instanceId,r&&styles.instanceIdSelected],numberOfLines:1,children:t.id}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.instanceBadges,children:[t.encrypted&&(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.badge,styles.badgeEncrypted],children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.badgeText,children:"\u{1F512} Encrypted"})}),t.readOnly&&(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.badge,styles.badgeReadOnly],children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.badgeText,children:"\u{1F441}\uFE0F Read-only"})})]})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.instanceRight,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.keyCount,children:t.keyCount}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.keyCountLabel,children:"keys"})]})]})}const styles=_reactNative.StyleSheet.create({container:{marginBottom:12},unavailableState:{backgroundColor:_sharedUi.macOSColors.semantic.warning+"15",borderRadius:12,padding:20,borderWidth:1,borderColor:_sharedUi.macOSColors.semantic.warning+"40",alignItems:"center",gap:12},unavailableTitle:{fontSize:14,fontWeight:"600",color:_sharedUi.macOSColors.semantic.warning},unavailableDescription:{fontSize:12,color:_sharedUi.night.color.textSecondary,textAlign:"center",lineHeight:18},emptyState:{backgroundColor:_sharedUi.night.color.surface,borderRadius:12,padding:20,borderWidth:1,borderColor:_sharedUi.night.color.border,alignItems:"center",gap:12},emptyStateTitle:{fontSize:14,fontWeight:"600",color:_sharedUi.night.color.text},emptyStateDescription:{fontSize:12,color:_sharedUi.night.color.textTertiary,textAlign:"center",lineHeight:18},refreshButton:{marginTop:8,paddingHorizontal:16,paddingVertical:8,backgroundColor:_sharedUi.night.color.accentSoft,borderRadius:8,borderWidth:1,borderColor:_sharedUi.night.color.accentBorderStrong},refreshButtonText:{fontSize:12,fontWeight:"600",color:_sharedUi.night.color.accent},selectorButton:{backgroundColor:_sharedUi.night.color.surface,borderRadius:12,borderWidth:1,borderColor:_sharedUi.night.color.border,padding:12,flexDirection:"row",alignItems:"center",justifyContent:"space-between",shadowColor:"#000000",shadowOpacity:.03,shadowRadius:8,shadowOffset:{width:0,height:2}},selectorContent:{flex:1},placeholderText:{fontSize:13,color:_sharedUi.night.color.placeholder,fontStyle:"italic"},dropdownArrow:{fontSize:10,color:_sharedUi.night.color.textTertiary,marginLeft:8},modalOverlay:{flex:1,backgroundColor:"rgba(0, 0, 0, 0.5)",justifyContent:"center",alignItems:"center",padding:20},dropdownContainer:{backgroundColor:_sharedUi.night.color.surface,borderRadius:16,borderWidth:1,borderColor:_sharedUi.night.color.border,width:"100%",maxWidth:500,maxHeight:"70%",shadowColor:"#000000",shadowOpacity:.2,shadowRadius:20,shadowOffset:{width:0,height:10},overflow:"hidden"},dropdownHeader:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",padding:16,borderBottomWidth:1,borderBottomColor:_sharedUi.night.color.separator},dropdownTitle:{fontSize:14,fontWeight:"600",color:_sharedUi.night.color.text},headerRefreshButton:{padding:4},headerRefreshText:{fontSize:18,color:_sharedUi.night.color.accent},dropdownList:{maxHeight:400},dropdownItem:{padding:12,borderBottomWidth:1,borderBottomColor:_sharedUi.night.color.separator},dropdownItemSelected:{backgroundColor:_sharedUi.night.color.accentSoft},instanceRow:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",gap:12},instanceLeft:{flex:1,gap:6},instanceId:{fontSize:13,fontWeight:"500",color:_sharedUi.night.color.text,fontFamily:_sharedUi.monoFont},instanceIdSelected:{fontWeight:"600",color:_sharedUi.night.color.accent},instanceBadges:{flexDirection:"row",flexWrap:"wrap",gap:6},badge:{paddingHorizontal:6,paddingVertical:2,borderRadius:4,borderWidth:1},badgeEncrypted:{backgroundColor:_sharedUi.macOSColors.semantic.success+"15",borderColor:_sharedUi.macOSColors.semantic.success+"40"},badgeReadOnly:{backgroundColor:_sharedUi.macOSColors.semantic.warning+"15",borderColor:_sharedUi.macOSColors.semantic.warning+"40"},badgeText:{fontSize:9,fontWeight:"500",color:_sharedUi.night.color.textSecondary},instanceRight:{alignItems:"flex-end"},keyCount:{fontSize:16,fontWeight:"600",color:_sharedUi.night.color.text,fontFamily:_sharedUi.monoFont},keyCountLabel:{fontSize:9,color:_sharedUi.night.color.textTertiary,textTransform:"uppercase",letterSpacing:.5}});
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.MMKVInstanceSelector=MMKVInstanceSelector;var _storageLabels=require("../utils/storageLabels");var _react=require("react");var _reactNative=require("react-native");var _sharedUi=require("@buoy-gg/shared-ui");var _useMMKVInstances=require("../hooks/useMMKVInstances");var _mmkvAvailability=require("../utils/mmkvAvailability");var _jsxRuntime=require("react/jsx-runtime");function MMKVInstanceSelector({selectedInstanceId:t,onSelectInstance:r,showRefreshButton:n=true}){const[c,o]=(0,_react.useState)(false);const{instances:i,instanceCount:a,refresh:s}=(0,_useMMKVInstances.useMMKVInstances)(false);const l=i.find(e=>e.id===t);const d=e=>{r(e);o(false)};if(!(0,_mmkvAvailability.isMMKVAvailable)()){return(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.container,children:(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.unavailableState,children:[(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.unavailableTitle,children:[_storageLabels.storageLabels.mmkv," Not Available"]}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.unavailableDescription,children:(0,_mmkvAvailability.getMMKVUnavailableMessage)()})]})})}if(a===0){return(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.container,children:(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.emptyState,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.emptyStateTitle,children:"No MMKV Instances Registered"}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.emptyStateDescription,children:"Register MMKV instances using registerMMKVInstance() to monitor them in dev tools."}),n&&(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:styles.refreshButton,onPress:s,activeOpacity:.7,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.refreshButtonText,children:"\u21BB Refresh"})})]})})}return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.container,children:[(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{style:styles.selectorButton,onPress:()=>o(true),activeOpacity:.7,children:[(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.selectorContent,children:l?(0,_jsxRuntime.jsx)(InstanceRow,{instance:l,isSelected:true}):(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.placeholderText,children:"Select MMKV Instance"})}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.dropdownArrow,children:"\u25BC"})]}),(0,_jsxRuntime.jsx)(_reactNative.Modal,{visible:c,transparent:true,animationType:"fade",onRequestClose:()=>o(false),children:(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:styles.modalOverlay,activeOpacity:1,onPress:()=>o(false),children:(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.dropdownContainer,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.dropdownHeader,children:[(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.dropdownTitle,children:["Select MMKV Instance (",a,")"]}),n&&(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:styles.headerRefreshButton,onPress:s,activeOpacity:.7,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.headerRefreshText,children:"\u21BB"})})]}),(0,_jsxRuntime.jsx)(_reactNative.ScrollView,{keyboardShouldPersistTaps:"handled",style:styles.dropdownList,children:i.map(e=>(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:[styles.dropdownItem,e.id===t&&styles.dropdownItemSelected],onPress:()=>d(e.id),activeOpacity:.7,children:(0,_jsxRuntime.jsx)(InstanceRow,{instance:e,isSelected:e.id===t})},e.id))})]})})})]})}function InstanceRow({instance:t,isSelected:r}){return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.instanceRow,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.instanceLeft,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.instanceId,r&&styles.instanceIdSelected],numberOfLines:1,children:t.id}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.instanceBadges,children:[t.encrypted&&(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.badge,styles.badgeEncrypted],children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.badgeText,children:"\u{1F512} Encrypted"})}),t.readOnly&&(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.badge,styles.badgeReadOnly],children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.badgeText,children:"\u{1F441}\uFE0F Read-only"})})]})]}),(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.instanceRight,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.keyCount,children:t.keyCount}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.keyCountLabel,children:"keys"})]})]})}const styles=_reactNative.StyleSheet.create({container:{marginBottom:12},unavailableState:{backgroundColor:_sharedUi.macOSColors.semantic.warning+"15",borderRadius:12,padding:20,borderWidth:1,borderColor:_sharedUi.macOSColors.semantic.warning+"40",alignItems:"center",gap:12},unavailableTitle:{fontSize:14,fontWeight:"600",color:_sharedUi.macOSColors.semantic.warning},unavailableDescription:{fontSize:12,color:_sharedUi.night.color.textSecondary,textAlign:"center",lineHeight:18},emptyState:{backgroundColor:_sharedUi.night.color.surface,borderRadius:12,padding:20,borderWidth:1,borderColor:_sharedUi.night.color.border,alignItems:"center",gap:12},emptyStateTitle:{fontSize:14,fontWeight:"600",color:_sharedUi.night.color.text},emptyStateDescription:{fontSize:12,color:_sharedUi.night.color.textTertiary,textAlign:"center",lineHeight:18},refreshButton:{marginTop:8,paddingHorizontal:16,paddingVertical:8,backgroundColor:_sharedUi.night.color.accentSoft,borderRadius:8,borderWidth:1,borderColor:_sharedUi.night.color.accentBorderStrong},refreshButtonText:{fontSize:12,fontWeight:"600",color:_sharedUi.night.color.accent},selectorButton:{backgroundColor:_sharedUi.night.color.surface,borderRadius:12,borderWidth:1,borderColor:_sharedUi.night.color.border,padding:12,flexDirection:"row",alignItems:"center",justifyContent:"space-between",shadowColor:"#000000",shadowOpacity:.03,shadowRadius:8,shadowOffset:{width:0,height:2}},selectorContent:{flex:1},placeholderText:{fontSize:13,color:_sharedUi.night.color.placeholder,fontStyle:"italic"},dropdownArrow:{fontSize:10,color:_sharedUi.night.color.textTertiary,marginLeft:8},modalOverlay:{flex:1,backgroundColor:"rgba(0, 0, 0, 0.5)",justifyContent:"center",alignItems:"center",padding:20},dropdownContainer:{backgroundColor:_sharedUi.night.color.surface,borderRadius:16,borderWidth:1,borderColor:_sharedUi.night.color.border,width:"100%",maxWidth:500,maxHeight:"70%",shadowColor:"#000000",shadowOpacity:.2,shadowRadius:20,shadowOffset:{width:0,height:10},overflow:"hidden"},dropdownHeader:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",padding:16,borderBottomWidth:1,borderBottomColor:_sharedUi.night.color.separator},dropdownTitle:{fontSize:14,fontWeight:"600",color:_sharedUi.night.color.text},headerRefreshButton:{padding:4},headerRefreshText:{fontSize:18,color:_sharedUi.night.color.accent},dropdownList:{maxHeight:400},dropdownItem:{padding:12,borderBottomWidth:1,borderBottomColor:_sharedUi.night.color.separator},dropdownItemSelected:{backgroundColor:_sharedUi.night.color.accentSoft},instanceRow:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",gap:12},instanceLeft:{flex:1,gap:6},instanceId:{fontSize:13,fontWeight:"500",color:_sharedUi.night.color.text,fontFamily:_sharedUi.monoFont},instanceIdSelected:{fontWeight:"600",color:_sharedUi.night.color.accent},instanceBadges:{flexDirection:"row",flexWrap:"wrap",gap:6},badge:{paddingHorizontal:6,paddingVertical:2,borderRadius:4,borderWidth:1},badgeEncrypted:{backgroundColor:_sharedUi.macOSColors.semantic.success+"15",borderColor:_sharedUi.macOSColors.semantic.success+"40"},badgeReadOnly:{backgroundColor:_sharedUi.macOSColors.semantic.warning+"15",borderColor:_sharedUi.macOSColors.semantic.warning+"40"},badgeText:{fontSize:9,fontWeight:"500",color:_sharedUi.night.color.textSecondary},instanceRight:{alignItems:"flex-end"},keyCount:{fontSize:16,fontWeight:"600",color:_sharedUi.night.color.text,fontFamily:_sharedUi.monoFont},keyCountLabel:{fontSize:9,color:_sharedUi.night.color.textTertiary,textTransform:"uppercase",letterSpacing:.5}});
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.FREE_TIER_EVENT_LIMIT=void 0;exports.StorageModalWithTabs=StorageModalWithTabs;exports.StorageToolView=StorageToolView;var _react=require("react");var _reactNative=require("react-native");var _appAsyncStorage=_interopRequireDefault(require("../utils/appAsyncStorage"));var _sharedUi=require("@buoy-gg/shared-ui");var _StorageBrowserMode=require("./StorageBrowserMode");var _StorageTypeFilterBar=require("./StorageTypeFilterBar");var _clearAllStorage=require("../utils/clearAllStorage");var _useStorageEvents=require("../hooks/useStorageEvents");var _StorageEventDetailContent=require("./StorageEventDetailContent");var _StorageEventFilterView=require("./StorageEventFilterView");var _StorageEventCard=require("./StorageEventCard");var _license=require("@buoy-gg/license");var _jsxRuntime=require("react/jsx-runtime");function _interopRequireDefault(o){return o&&o.__esModule?o:{default:o}}const FREE_TIER_EVENT_LIMIT=exports.FREE_TIER_EVENT_LIMIT=_sharedUi.TIER_LIMITS["storage.events"].free;const ASYNC_STORAGE_BACKEND={getItem:o=>_appAsyncStorage.default.getItem(o),setItem:(o,p)=>_appAsyncStorage.default.setItem(o,p)};const TAB_PERSISTENCE={storage:ASYNC_STORAGE_BACKEND,parse:o=>o==="browser"||o==="events"?o:void 0,serialize:o=>o};const BOOLEAN_PERSISTENCE={storage:ASYNC_STORAGE_BACKEND,parse:o=>o==="true",serialize:o=>o.toString()};const STRING_SET_PERSISTENCE={storage:ASYNC_STORAGE_BACKEND,parse:o=>new Set(JSON.parse(o)),serialize:o=>JSON.stringify(Array.from(o))};const IGNORED_PATTERNS_PERSISTENCE={...STRING_SET_PERSISTENCE,parse:o=>{const p=JSON.parse(o);if(!p.includes("@react_buoy"))p.push("@react_buoy");return new Set(p)}};function StorageModalWithTabs({visible:o,onClose:p,onBack:F,onMinimize:oe,enableSharedModalDimensions:ne=false,requiredStorageKeys:ae=[],inline:se=false,onTabChange:O,onRefresh:z,onEventSelect:C}){const De=(0,_license.useIsPro)();const I=(0,_sharedUi.useLimit)("storage.events");const[m,le]=(0,_sharedUi.usePersistedState)(_sharedUi.devToolsStorageKeys.storage.activeTab(),"browser",TAB_PERSISTENCE);(0,_react.useEffect)(()=>{O?.(m)},[m,O]);const[L,q]=(0,_react.useState)("");const[B,k]=(0,_react.useState)(null);const[M,P]=(0,_react.useState)(false);const[W,ie]=(0,_sharedUi.usePersistedState)(_sharedUi.devToolsStorageKeys.storage.isMonitoring(),true,BOOLEAN_PERSISTENCE);const{events:T,clearEvents:$,isCapturing:ce}=(0,_useStorageEvents.useStorageEvents)({enabled:W});const[A,b]=(0,_react.useState)(null);const[S,D]=(0,_react.useState)(null);const[c,d]=(0,_react.useState)(null);const[j,h]=(0,_react.useState)(0);const[x,_]=(0,_react.useState)(false);const[u,G]=(0,_sharedUi.usePersistedState)(_sharedUi.devToolsStorageKeys.storage.eventFilters(),new Set(["@react_buoy","@RNAsyncStorage","redux-persist","persist:"]),IGNORED_PATTERNS_PERSISTENCE);const[f,J]=(0,_react.useState)("all");const[g,de]=(0,_react.useState)(new Set(["async","mmkv","secure"]));const[ue,ge]=(0,_sharedUi.usePersistedState)(_sharedUi.devToolsStorageKeys.storage.pinnedKeys(),new Set,STRING_SET_PERSISTENCE);const _e=(0,_react.useRef)(null);const Q=W&&ce;const[R,ye]=(0,_react.useState)("bottomSheet");const pe=(0,_react.useCallback)(e=>{ye(e)},[]);const Se=(0,_react.useCallback)(()=>{ie(e=>!e)},[]);const he=(0,_react.useCallback)(()=>{$();b(null);h(0)},[$]);const fe=(0,_react.useCallback)(e=>{D(e);d(null)},[]);const U=(0,_react.useCallback)(()=>{D(null);d(null)},[]);const Y=(0,_react.useCallback)(e=>{G(t=>{const r=new Set(t);if(r.has(e)){r.delete(e)}else{r.add(e)}return r})},[]);const X=(0,_react.useCallback)(e=>{G(t=>new Set([...t,e]))},[]);const ve=(0,_react.useCallback)(e=>{ge(t=>{const r=new Set(t);if(r.has(e)){r.delete(e)}else{r.add(e)}return r})},[]);const me=(0,_react.useCallback)(()=>{_(!x)},[x]);const Te=(0,_react.useCallback)(e=>{de(t=>{const r=new Set(t);if(r.has(e)){r.delete(e)}else{r.add(e)}return r})},[]);const H=(0,_react.useRef)([]);const be=(0,_react.useCallback)(()=>{const e=H.current;return{timestamp:new Date().toISOString(),totalKeys:e.length,asyncStorage:e.filter(t=>t.storageType==="async").reduce((t,r)=>{t[r.key]=(0,_sharedUi.truncatePayload)(r.value);return t},{}),mmkv:e.filter(t=>t.storageType==="mmkv").reduce((t,r)=>{const n=r.instanceId||"default";if(!t[n])t[n]={};t[n][r.key]=(0,_sharedUi.truncatePayload)(r.value);return t},{}),secure:e.filter(t=>t.storageType==="secure").reduce((t,r)=>{t[r.key]=(0,_sharedUi.truncatePayload)(r.value);return t},{})}},[]);const Re=(0,_react.useCallback)(async()=>{_reactNative.Alert.alert("Clear Storage","Choose what to clear:",[{text:"Cancel",style:"cancel"},{text:"Clear App Storage",onPress:async()=>{try{await(0,_clearAllStorage.clearAllAppStorage)()}catch(e){_reactNative.Alert.alert("Error","Failed to clear app storage")}}},{text:"Clear All (Including Dev Tools)",style:"destructive",onPress:async()=>{try{await(0,_clearAllStorage.clearAllStorageIncludingDevTools)()}catch(e){_reactNative.Alert.alert("Error","Failed to clear all storage")}}}])},[]);const w=e=>{const t=(0,_sharedUi.parseValue)(e);if(t===null)return"null";if(t===void 0)return"undefined";if(Array.isArray(t))return"array";if(typeof t==="boolean")return"boolean";if(typeof t==="number")return"number";if(typeof t==="string")return"string";if(typeof t==="object")return"object";return"undefined"};const[Z,xe]=(0,_react.useState)([]);(0,_react.useEffect)(()=>{const e=async()=>{try{const t=await _appAsyncStorage.default.getAllKeys();xe([...t].sort())}catch(t){}};if(o){e()}},[o]);const Ee=(0,_react.useMemo)(()=>{const e=new Set(Z);T.forEach(t=>{if(t.data?.key){e.add(t.data.key)}});return Array.from(e).sort()},[T,Z]);const l=(0,_react.useMemo)(()=>{const e=new Map;T.forEach(t=>{if(!t.data?.key)return;const r=t.data.key;if(!g.has(t.storageType))return;const n=Array.from(u).some(v=>r.includes(v));if(n)return;const a=e.get(r);if(!a){e.set(r,{key:r,lastEvent:t,events:[t],totalOperations:1,currentValue:t.data.value,valueType:w(t.data.value),storageTypes:new Set([t.storageType])})}else{a.events.push(t);a.totalOperations++;a.storageTypes.add(t.storageType);if(t.timestamp>a.lastEvent.timestamp){a.lastEvent=t;a.currentValue=t.data.value;a.valueType=w(t.data.value)}}});return Array.from(e.values()).sort((t,r)=>r.lastEvent.timestamp.getTime()-t.lastEvent.timestamp.getTime())},[T,u,g]);const s=(0,_react.useMemo)(()=>{if(!A)return null;return l.find(e=>e.key===A)||null},[A,l]);const Ce=(0,_react.useMemo)(()=>{const e={};l.forEach(t=>{e[t.key]=t.totalOperations});return e},[l]);const Ie=(0,_react.useMemo)(()=>{const e={};l.forEach(t=>{e[t.key]=t.lastEvent.timestamp.getTime()});return e},[l]);const y=(0,_react.useMemo)(()=>{if(!S)return null;return l.find(e=>e.key===S)||null},[S,l]);(0,_react.useEffect)(()=>{if(!C)return;const e=s?s:c!==null?y:null;const t=s?j:c;if(!e||t==null)return;const r=[...e.events].sort((v,V)=>v.timestamp.getTime()-V.timestamp.getTime());const n=r[t];const a=r[t-1];if(n)C(n);if(a)C(a)},[C,s,j,y,c]);const E=(0,_react.useMemo)(()=>{return T.filter(e=>{if(!e.data?.key)return false;if(!g.has(e.storageType))return false;const t=e.data.key;return!Array.from(u).some(r=>t.includes(r))})},[T,u,g]);const ke=(0,_react.useMemo)(()=>(0,_StorageTypeFilterBar.countByStorageType)(E),[E]);const i=(0,_react.useMemo)(()=>{if(f==="all")return E;return E.filter(e=>e.storageType===f)},[E,f]);const je=(0,_react.useCallback)(()=>{return i.map(e=>({key:e.data?.key,action:e.action,value:(0,_sharedUi.truncatePayload)(e.data?.value),storageType:e.storageType,timestamp:e.timestamp.toISOString()}))},[i]);const we=(0,_react.useMemo)(()=>i.slice(0,I),[i,I]);const K=(0,_react.useMemo)(()=>Math.max(0,i.length-I),[i.length,I]);const Fe=.8;const Be=(0,_react.useCallback)(e=>e.id,[]);const ee=(0,_react.useCallback)(e=>{const t=l.find(a=>a.key===e.data?.key);if(!t)return;const r=[...t.events].sort((a,v)=>a.timestamp.getTime()-v.timestamp.getTime());const n=r.findIndex(a=>a.timestamp.getTime()===e.timestamp.getTime());b(t.key);h(n>=0?n:0)},[l]);const Me=(0,_react.useCallback)(({item:e})=>{const t={key:e.data?.key||"",lastAction:e.action,totalOperations:1,lastEventTimestamp:e.timestamp,storageTypes:new Set([e.storageType]),valueType:w(e.data?.value)};return(0,_jsxRuntime.jsx)(_StorageEventCard.StorageEventCard,{data:t,onPress:()=>ee(e),testID:`buoy-storage-event-${e.id}`})},[ee]);if(!o)return null;const Pe=ne?_sharedUi.devToolsStorageKeys.modal.root():_sharedUi.devToolsStorageKeys.storage.modal();const te=()=>{if(x){return(0,_jsxRuntime.jsx)(_StorageEventFilterView.StorageEventFilterView,{ignoredPatterns:u,onTogglePattern:Y,onAddPattern:X,availableKeys:Ee,enabledStorageTypes:g,onToggleStorageType:Te})}if(m==="browser"){if(S&&y){if(c!==null){return(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.contentWrapper,children:(0,_jsxRuntime.jsx)(_StorageEventDetailContent.StorageEventDetailContent,{conversation:y,selectedEventIndex:c,onEventIndexChange:d,disableInternalFooter:true})})}const t=[...y.events].sort((n,a)=>n.timestamp.getTime()-a.timestamp.getTime());const r=[...t].reverse();return(0,_jsxRuntime.jsx)(_reactNative.FlatList,{testID:"buoy-storage-history-list",style:styles.flexFill,data:r,keyExtractor:n=>n.id,renderItem:({item:n})=>{const a=t.findIndex(V=>V.timestamp.getTime()===n.timestamp.getTime());const v={key:n.data?.key||"",lastAction:n.action,totalOperations:1,lastEventTimestamp:n.timestamp,storageTypes:new Set([n.storageType]),valueType:w(n.data?.value)};return(0,_jsxRuntime.jsx)(_StorageEventCard.StorageEventCard,{data:v,onPress:()=>d(a>=0?a:0),testID:`buoy-storage-history-event-${n.id}`})},contentContainerStyle:styles.listContent,ItemSeparatorComponent:()=>(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.separator}),initialNumToRender:20})}return(0,_jsxRuntime.jsx)(_StorageBrowserMode.StorageBrowserMode,{requiredStorageKeys:ae,ignoredPatterns:u,onTogglePattern:Y,onAddPattern:X,searchQuery:L,storageDataRef:H,eventCountByKey:Ce,lastWriteByKey:Ie,onViewHistory:fe,enabledStorageTypes:g,pinnedKeys:ue,onTogglePin:ve,applySafeAreaInset:R==="bottomSheet",storageTypeFilter:f,onStorageTypeFilterChange:J,detailKey:B,onOpenKey:k,onCloseDetail:()=>k(null)})}if(s){return(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.contentWrapper,children:(0,_jsxRuntime.jsx)(_StorageEventDetailContent.StorageEventDetailContent,{conversation:s,selectedEventIndex:j,onEventIndexChange:h,disableInternalFooter:true})})}const e=(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.eventFilterBar,children:(0,_jsxRuntime.jsx)(_StorageTypeFilterBar.StorageTypeFilterBar,{active:f,onChange:J,counts:ke})});if(i.length===0){const t=f!=="all";return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.flexFill,children:[e,(0,_jsxRuntime.jsx)(_sharedUi.ToolEmptyState,{testID:"buoy-storage-events-empty",...!Q?{otto:"paused",title:"Event listener is paused",message:"Press play to start monitoring"}:t?{otto:"filtering",title:`No ${f} events`,message:"Other backends have events \u2014 pick All Types to see them"}:{otto:"listening",title:"No storage events yet",message:"Storage operations will appear here"}})]})}return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.flexFill,children:[e,(0,_jsxRuntime.jsx)(_reactNative.FlatList,{testID:"buoy-storage-events-list",style:styles.flexFill,data:we,renderItem:Me,keyExtractor:Be,onEndReachedThreshold:Fe,contentContainerStyle:styles.listContent,ListFooterComponent:K>0?(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.lockedBannerContainer,children:(0,_jsxRuntime.jsx)(_sharedUi.ProFeatureBanner,{featureName:`${K} event${K>1?"s":""} locked`,description:"Upgrade to Pro to unlock full event history"})}):null,initialNumToRender:10,maxToRenderPerBatch:10,windowSize:10})]})};const N=s&&s.events.length>1?(0,_jsxRuntime.jsx)(_StorageEventDetailContent.StorageEventDetailFooter,{conversation:s,selectedEventIndex:j,onEventIndexChange:h,applySafeAreaInset:R==="bottomSheet"}):y&&c!==null&&y.events.length>1?(0,_jsxRuntime.jsx)(_StorageEventDetailContent.StorageEventDetailFooter,{conversation:y,selectedEventIndex:c,onEventIndexChange:d,applySafeAreaInset:R==="bottomSheet"}):null;const Ae=x?()=>_(false):c!==null?()=>d(null):S?U:s?()=>{b(null);h(0)}:F;const re=x?(0,_jsxRuntime.jsxs)(_sharedUi.ModalHeader,{children:[(0,_jsxRuntime.jsx)(_sharedUi.ModalHeader.Navigation,{onBack:()=>_(false)}),(0,_jsxRuntime.jsx)(_sharedUi.ModalHeader.Content,{title:"Filters"})]}):S?(0,_jsxRuntime.jsxs)(_sharedUi.ModalHeader,{children:[(0,_jsxRuntime.jsx)(_sharedUi.ModalHeader.Navigation,{onBack:c!==null?()=>d(null):U}),(0,_jsxRuntime.jsx)(_sharedUi.ModalHeader.Content,{title:`${S} History`,centered:true})]}):s?(0,_jsxRuntime.jsxs)(_sharedUi.ModalHeader,{children:[(0,_jsxRuntime.jsx)(_sharedUi.ModalHeader.Navigation,{onBack:()=>{b(null);h(0)}}),(0,_jsxRuntime.jsx)(_sharedUi.ModalHeader.Content,{title:s.key})]}):B?(0,_jsxRuntime.jsxs)(_sharedUi.ModalHeader,{children:[(0,_jsxRuntime.jsx)(_sharedUi.ModalHeader.Navigation,{onBack:()=>k(null)}),(0,_jsxRuntime.jsx)(_sharedUi.ModalHeader.Content,{title:B.key,centered:true,testID:"buoy-storage-detail-title"})]}):(0,_jsxRuntime.jsxs)(_sharedUi.ModalHeader,{children:[F&&(0,_jsxRuntime.jsx)(_sharedUi.ModalHeader.Navigation,{onBack:F}),(0,_jsxRuntime.jsx)(_sharedUi.ModalHeader.Content,{title:"",children:M?(0,_jsxRuntime.jsx)(_sharedUi.SearchBar,{value:L,onChange:q,onClear:()=>{q("");P(false)},placeholder:"Search storage keys...",testID:"buoy-storage-search",autoFocus:true,onSubmitEditing:()=>P(false),returnKeyType:"search",containerStyle:styles.headerSearchContainer}):(0,_jsxRuntime.jsx)(_sharedUi.TabSelector,{tabs:[{key:"browser",label:"Storage"},{key:"events",label:`Events${i.length>0?` (${i.length})`:""}`}],activeTab:m,testIDPrefix:"buoy-storage-tab",onTabChange:e=>{le(e);D(null);d(null);b(null);h(0);k(null)}})}),(0,_jsxRuntime.jsxs)(_sharedUi.ModalHeader.Actions,{children:[z&&!M?(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{onPress:z,style:styles.iconButton,testID:"buoy-storage-refresh",accessibilityLabel:"Refresh storage",accessibilityRole:"button",children:(0,_jsxRuntime.jsx)(_sharedUi.RefreshCw,{size:14,color:_sharedUi.night.color.textSecondary})}):null,(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{onPress:me,testID:"buoy-storage-filters",accessibilityLabel:"Storage filters",accessibilityRole:"button",style:[styles.iconButton,(u.size>0||g.size<3)&&styles.activeFilterButton],children:(0,_jsxRuntime.jsx)(_sharedUi.Filter,{size:14,color:u.size>0||g.size<3?_sharedUi.night.color.accent:_sharedUi.night.color.textSecondary})}),m==="browser"&&!M&&(0,_jsxRuntime.jsxs)(_jsxRuntime.Fragment,{children:[(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{onPress:()=>P(true),testID:"buoy-storage-search-open",accessibilityLabel:"Open search",accessibilityRole:"button",style:styles.iconButton,children:(0,_jsxRuntime.jsx)(_sharedUi.Search,{size:14,color:_sharedUi.night.color.textSecondary})}),(0,_jsxRuntime.jsx)(_sharedUi.ToolbarCopyButton,{value:be,disabled:H.current.length===0,buttonStyle:styles.iconButton,testID:"buoy-storage-copy"})]}),m==="events"&&(0,_jsxRuntime.jsxs)(_jsxRuntime.Fragment,{children:[(0,_jsxRuntime.jsx)(_sharedUi.ToolbarCopyButton,{value:je,disabled:i.length===0,buttonStyle:styles.iconButton,testID:"buoy-storage-events-copy"}),(0,_jsxRuntime.jsx)(_sharedUi.PowerToggleButton,{isEnabled:Q,onToggle:Se,accessibilityLabel:"Toggle storage event monitoring",testID:"buoy-storage-power"}),(0,_jsxRuntime.jsx)(_sharedUi.ToolbarClearButton,{onPress:he,buttonStyle:styles.iconButton,testID:"buoy-storage-clear-events"})]})]})]});if(se){return(0,_jsxRuntime.jsx)(_sharedUi.TickProvider,{children:(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.inlineRoot,children:[(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.inlineHeader,..._sharedUi.windowDragProps,children:re}),te(),N]})})}return(0,_jsxRuntime.jsx)(_sharedUi.TickProvider,{children:(0,_jsxRuntime.jsx)(_sharedUi.JsModal,{visible:o,onClose:p,onBack:Ae,onMinimize:oe,persistenceKey:Pe,header:{showToggleButton:true,customContent:re},onModeChange:pe,enablePersistence:true,initialMode:"bottomSheet",enableGlitchEffects:true,styles:{},footer:N,footerHeight:N?68:0,disableScrollWrapper:true,children:te()})})}function StorageToolView(o={}){return(0,_jsxRuntime.jsx)(StorageModalWithTabs,{...o,inline:true,visible:true,onClose:()=>{}})}const styles=_reactNative.StyleSheet.create({inlineRoot:{flex:1,minHeight:0,backgroundColor:"transparent"},inlineHeader:{paddingHorizontal:12,paddingVertical:8,borderBottomWidth:1,borderBottomColor:_sharedUi.macOSColors.border.default,backgroundColor:"transparent"},headerSearchContainer:{flex:1},flexFill:{flex:1},iconButton:{width:32,height:32,borderRadius:8,backgroundColor:_sharedUi.night.color.buttonSurface,borderWidth:1,borderColor:_sharedUi.night.color.border,alignItems:"center",justifyContent:"center"},activeFilterButton:{backgroundColor:_sharedUi.night.color.accentSoft,borderColor:_sharedUi.night.color.accentBorderStrong},separator:{height:8},listContent:{paddingVertical:6},lockedBannerContainer:{marginTop:8,marginHorizontal:16},eventFilterBar:{paddingHorizontal:12,paddingTop:8,paddingBottom:4},emptyState:{flex:1,justifyContent:"center",alignItems:"center",padding:32},emptyTitle:{color:_sharedUi.night.color.text,fontSize:16,fontWeight:"600",marginTop:16,marginBottom:8,fontFamily:_sharedUi.monoFont,letterSpacing:.5,textTransform:"uppercase"},emptySubtitle:{color:_sharedUi.night.color.textSecondary,fontSize:14,textAlign:"center",fontFamily:_sharedUi.monoFont},eventNavigation:{flexDirection:"row",alignItems:"center",gap:8,paddingHorizontal:8},navButton:{padding:4,borderRadius:4},navButtonDisabled:{opacity:.3},eventCounter:{color:_sharedUi.night.color.text,fontSize:12,fontWeight:"600",fontFamily:_sharedUi.monoFont,paddingHorizontal:8},headerTopRow:{flexDirection:"row",alignItems:"center",gap:8,marginBottom:12},keyNameContainer:{flex:1,flexDirection:"row",alignItems:"center",gap:6,backgroundColor:_sharedUi.night.color.surfaceElevated,paddingHorizontal:10,paddingVertical:4,borderRadius:6,borderWidth:1,borderColor:_sharedUi.night.color.border,height:28},keyNameText:{flex:1,fontSize:13,fontWeight:"600",color:_sharedUi.night.color.accent,fontFamily:_sharedUi.monoFont,letterSpacing:.5},contentWrapper:{flex:1}});
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.FREE_TIER_EVENT_LIMIT=void 0;exports.StorageModalWithTabs=StorageModalWithTabs;exports.StorageToolView=StorageToolView;var _react=require("react");var _reactNative=require("react-native");var _appAsyncStorage=_interopRequireDefault(require("../utils/appAsyncStorage"));var _sharedUi=require("@buoy-gg/shared-ui");var _StorageBrowserMode=require("./StorageBrowserMode");var _StorageTypeFilterBar=require("./StorageTypeFilterBar");var _clearAllStorage=require("../utils/clearAllStorage");var _useStorageEvents=require("../hooks/useStorageEvents");var _StorageEventDetailContent=require("./StorageEventDetailContent");var _StorageEventFilterView=require("./StorageEventFilterView");var _StorageEventCard=require("./StorageEventCard");var _license=require("@buoy-gg/license");var _jsxRuntime=require("react/jsx-runtime");function _interopRequireDefault(o){return o&&o.__esModule?o:{default:o}}const FREE_TIER_EVENT_LIMIT=exports.FREE_TIER_EVENT_LIMIT=_sharedUi.TIER_LIMITS["storage.events"].free;const ASYNC_STORAGE_BACKEND={getItem:o=>_appAsyncStorage.default.getItem(o),setItem:(o,p)=>_appAsyncStorage.default.setItem(o,p)};const TAB_PERSISTENCE={storage:ASYNC_STORAGE_BACKEND,parse:o=>o==="browser"||o==="events"?o:void 0,serialize:o=>o};const BOOLEAN_PERSISTENCE={storage:ASYNC_STORAGE_BACKEND,parse:o=>o==="true",serialize:o=>o.toString()};const STRING_SET_PERSISTENCE={storage:ASYNC_STORAGE_BACKEND,parse:o=>new Set(JSON.parse(o)),serialize:o=>JSON.stringify(Array.from(o))};const IGNORED_PATTERNS_PERSISTENCE={...STRING_SET_PERSISTENCE,parse:o=>{const p=JSON.parse(o);if(!p.includes("@react_buoy"))p.push("@react_buoy");return new Set(p)}};function StorageModalWithTabs({visible:o,onClose:p,onBack:F,onMinimize:oe,enableSharedModalDimensions:ne=false,requiredStorageKeys:ae=[],inline:se=false,onTabChange:O,onRefresh:z,onEventSelect:C}){const De=(0,_license.useIsPro)();const I=(0,_sharedUi.useLimit)("storage.events");const[m,le]=(0,_sharedUi.usePersistedState)(_sharedUi.devToolsStorageKeys.storage.activeTab(),"browser",TAB_PERSISTENCE);(0,_react.useEffect)(()=>{O?.(m)},[m,O]);const[L,q]=(0,_react.useState)("");const[B,k]=(0,_react.useState)(null);const[P,M]=(0,_react.useState)(false);const[W,ie]=(0,_sharedUi.usePersistedState)(_sharedUi.devToolsStorageKeys.storage.isMonitoring(),true,BOOLEAN_PERSISTENCE);const{events:T,clearEvents:$,isCapturing:ce}=(0,_useStorageEvents.useStorageEvents)({enabled:W});const[A,b]=(0,_react.useState)(null);const[S,D]=(0,_react.useState)(null);const[c,d]=(0,_react.useState)(null);const[j,h]=(0,_react.useState)(0);const[x,_]=(0,_react.useState)(false);const[u,G]=(0,_sharedUi.usePersistedState)(_sharedUi.devToolsStorageKeys.storage.eventFilters(),new Set(["@react_buoy","@RNAsyncStorage","redux-persist","persist:"]),IGNORED_PATTERNS_PERSISTENCE);const[f,J]=(0,_react.useState)("all");const[g,de]=(0,_react.useState)(new Set(["async","mmkv","secure"]));const[ue,ge]=(0,_sharedUi.usePersistedState)(_sharedUi.devToolsStorageKeys.storage.pinnedKeys(),new Set,STRING_SET_PERSISTENCE);const _e=(0,_react.useRef)(null);const Q=W&&ce;const[R,ye]=(0,_react.useState)("bottomSheet");const pe=(0,_react.useCallback)(e=>{ye(e)},[]);const Se=(0,_react.useCallback)(()=>{ie(e=>!e)},[]);const he=(0,_react.useCallback)(()=>{$();b(null);h(0)},[$]);const fe=(0,_react.useCallback)(e=>{D(e);d(null)},[]);const U=(0,_react.useCallback)(()=>{D(null);d(null)},[]);const Y=(0,_react.useCallback)(e=>{G(t=>{const r=new Set(t);if(r.has(e)){r.delete(e)}else{r.add(e)}return r})},[]);const X=(0,_react.useCallback)(e=>{G(t=>new Set([...t,e]))},[]);const ve=(0,_react.useCallback)(e=>{ge(t=>{const r=new Set(t);if(r.has(e)){r.delete(e)}else{r.add(e)}return r})},[]);const me=(0,_react.useCallback)(()=>{_(!x)},[x]);const Te=(0,_react.useCallback)(e=>{de(t=>{const r=new Set(t);if(r.has(e)){r.delete(e)}else{r.add(e)}return r})},[]);const H=(0,_react.useRef)([]);const be=(0,_react.useCallback)(()=>{const e=H.current;return{timestamp:new Date().toISOString(),totalKeys:e.length,asyncStorage:e.filter(t=>t.storageType==="async").reduce((t,r)=>{t[r.key]=(0,_sharedUi.truncatePayload)(r.value);return t},{}),mmkv:e.filter(t=>t.storageType==="mmkv").reduce((t,r)=>{const n=r.instanceId||"default";if(!t[n])t[n]={};t[n][r.key]=(0,_sharedUi.truncatePayload)(r.value);return t},{}),secure:e.filter(t=>t.storageType==="secure").reduce((t,r)=>{t[r.key]=(0,_sharedUi.truncatePayload)(r.value);return t},{})}},[]);const Re=(0,_react.useCallback)(async()=>{_reactNative.Alert.alert("Clear Storage","Choose what to clear:",[{text:"Cancel",style:"cancel"},{text:"Clear App Storage",onPress:async()=>{try{await(0,_clearAllStorage.clearAllAppStorage)()}catch(e){_reactNative.Alert.alert("Error","Failed to clear app storage")}}},{text:"Clear All (Including Dev Tools)",style:"destructive",onPress:async()=>{try{await(0,_clearAllStorage.clearAllStorageIncludingDevTools)()}catch(e){_reactNative.Alert.alert("Error","Failed to clear all storage")}}}])},[]);const w=e=>{const t=(0,_sharedUi.parseValue)(e);if(t===null)return"null";if(t===void 0)return"undefined";if(Array.isArray(t))return"array";if(typeof t==="boolean")return"boolean";if(typeof t==="number")return"number";if(typeof t==="string")return"string";if(typeof t==="object")return"object";return"undefined"};const[Z,xe]=(0,_react.useState)([]);(0,_react.useEffect)(()=>{const e=async()=>{try{const t=await _appAsyncStorage.default.getAllKeys();xe([...t].sort())}catch(t){}};if(o){e()}},[o]);const Ee=(0,_react.useMemo)(()=>{const e=new Set(Z);T.forEach(t=>{if(t.data?.key){e.add(t.data.key)}});return Array.from(e).sort()},[T,Z]);const l=(0,_react.useMemo)(()=>{const e=new Map;T.forEach(t=>{if(!t.data?.key)return;const r=t.data.key;if(!g.has(t.storageType))return;const n=Array.from(u).some(v=>r.includes(v));if(n)return;const a=e.get(r);if(!a){e.set(r,{key:r,lastEvent:t,events:[t],totalOperations:1,currentValue:t.data.value,valueType:w(t.data.value),storageTypes:new Set([t.storageType])})}else{a.events.push(t);a.totalOperations++;a.storageTypes.add(t.storageType);if(t.timestamp>a.lastEvent.timestamp){a.lastEvent=t;a.currentValue=t.data.value;a.valueType=w(t.data.value)}}});return Array.from(e.values()).sort((t,r)=>r.lastEvent.timestamp.getTime()-t.lastEvent.timestamp.getTime())},[T,u,g]);const s=(0,_react.useMemo)(()=>{if(!A)return null;return l.find(e=>e.key===A)||null},[A,l]);const Ce=(0,_react.useMemo)(()=>{const e={};l.forEach(t=>{e[t.key]=t.totalOperations});return e},[l]);const Ie=(0,_react.useMemo)(()=>{const e={};l.forEach(t=>{e[t.key]=t.lastEvent.timestamp.getTime()});return e},[l]);const y=(0,_react.useMemo)(()=>{if(!S)return null;return l.find(e=>e.key===S)||null},[S,l]);(0,_react.useEffect)(()=>{if(!C)return;const e=s?s:c!==null?y:null;const t=s?j:c;if(!e||t==null)return;const r=[...e.events].sort((v,V)=>v.timestamp.getTime()-V.timestamp.getTime());const n=r[t];const a=r[t-1];if(n)C(n);if(a)C(a)},[C,s,j,y,c]);const E=(0,_react.useMemo)(()=>{return T.filter(e=>{if(!e.data?.key)return false;if(!g.has(e.storageType))return false;const t=e.data.key;return!Array.from(u).some(r=>t.includes(r))})},[T,u,g]);const ke=(0,_react.useMemo)(()=>(0,_StorageTypeFilterBar.countByStorageType)(E),[E]);const i=(0,_react.useMemo)(()=>{if(f==="all")return E;return E.filter(e=>e.storageType===f)},[E,f]);const je=(0,_react.useCallback)(()=>{return i.map(e=>({key:e.data?.key,action:e.action,value:(0,_sharedUi.truncatePayload)(e.data?.value),storageType:e.storageType,timestamp:e.timestamp.toISOString()}))},[i]);const we=(0,_react.useMemo)(()=>i.slice(0,I),[i,I]);const K=(0,_react.useMemo)(()=>Math.max(0,i.length-I),[i.length,I]);const Fe=.8;const Be=(0,_react.useCallback)(e=>e.id,[]);const ee=(0,_react.useCallback)(e=>{const t=l.find(a=>a.key===e.data?.key);if(!t)return;const r=[...t.events].sort((a,v)=>a.timestamp.getTime()-v.timestamp.getTime());const n=r.findIndex(a=>a.timestamp.getTime()===e.timestamp.getTime());b(t.key);h(n>=0?n:0)},[l]);const Pe=(0,_react.useCallback)(({item:e})=>{const t={key:e.data?.key||"",lastAction:e.action,totalOperations:1,lastEventTimestamp:e.timestamp,storageTypes:new Set([e.storageType]),valueType:w(e.data?.value)};return(0,_jsxRuntime.jsx)(_StorageEventCard.StorageEventCard,{data:t,onPress:()=>ee(e),testID:`buoy-storage-event-${e.id}`})},[ee]);if(!o)return null;const Me=ne?_sharedUi.devToolsStorageKeys.modal.root():_sharedUi.devToolsStorageKeys.storage.modal();const te=()=>{if(x){return(0,_jsxRuntime.jsx)(_StorageEventFilterView.StorageEventFilterView,{ignoredPatterns:u,onTogglePattern:Y,onAddPattern:X,availableKeys:Ee,enabledStorageTypes:g,onToggleStorageType:Te})}if(m==="browser"){if(S&&y){if(c!==null){return(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.contentWrapper,children:(0,_jsxRuntime.jsx)(_StorageEventDetailContent.StorageEventDetailContent,{conversation:y,selectedEventIndex:c,onEventIndexChange:d,disableInternalFooter:true})})}const t=[...y.events].sort((n,a)=>n.timestamp.getTime()-a.timestamp.getTime());const r=[...t].reverse();return(0,_jsxRuntime.jsx)(_reactNative.FlatList,{keyboardShouldPersistTaps:"handled",testID:"buoy-storage-history-list",style:styles.flexFill,data:r,keyExtractor:n=>n.id,renderItem:({item:n})=>{const a=t.findIndex(V=>V.timestamp.getTime()===n.timestamp.getTime());const v={key:n.data?.key||"",lastAction:n.action,totalOperations:1,lastEventTimestamp:n.timestamp,storageTypes:new Set([n.storageType]),valueType:w(n.data?.value)};return(0,_jsxRuntime.jsx)(_StorageEventCard.StorageEventCard,{data:v,onPress:()=>d(a>=0?a:0),testID:`buoy-storage-history-event-${n.id}`})},contentContainerStyle:styles.listContent,ItemSeparatorComponent:()=>(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.separator}),initialNumToRender:20})}return(0,_jsxRuntime.jsx)(_StorageBrowserMode.StorageBrowserMode,{requiredStorageKeys:ae,ignoredPatterns:u,onTogglePattern:Y,onAddPattern:X,searchQuery:L,storageDataRef:H,eventCountByKey:Ce,lastWriteByKey:Ie,onViewHistory:fe,enabledStorageTypes:g,pinnedKeys:ue,onTogglePin:ve,applySafeAreaInset:R==="bottomSheet",storageTypeFilter:f,onStorageTypeFilterChange:J,detailKey:B,onOpenKey:k,onCloseDetail:()=>k(null)})}if(s){return(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.contentWrapper,children:(0,_jsxRuntime.jsx)(_StorageEventDetailContent.StorageEventDetailContent,{conversation:s,selectedEventIndex:j,onEventIndexChange:h,disableInternalFooter:true})})}const e=(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.eventFilterBar,children:(0,_jsxRuntime.jsx)(_StorageTypeFilterBar.StorageTypeFilterBar,{active:f,onChange:J,counts:ke})});if(i.length===0){const t=f!=="all";return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.flexFill,children:[e,(0,_jsxRuntime.jsx)(_sharedUi.ToolEmptyState,{testID:"buoy-storage-events-empty",...!Q?{otto:"paused",title:"Event listener is paused",message:"Press play to start monitoring"}:t?{otto:"filtering",title:`No ${f} events`,message:"Other backends have events \u2014 pick All Types to see them"}:{otto:"listening",title:"No storage events yet",message:"Storage operations will appear here"}})]})}return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.flexFill,children:[e,(0,_jsxRuntime.jsx)(_reactNative.FlatList,{keyboardShouldPersistTaps:"handled",testID:"buoy-storage-events-list",style:styles.flexFill,data:we,renderItem:Pe,keyExtractor:Be,onEndReachedThreshold:Fe,contentContainerStyle:styles.listContent,ListFooterComponent:K>0?(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.lockedBannerContainer,children:(0,_jsxRuntime.jsx)(_sharedUi.ProFeatureBanner,{featureName:`${K} event${K>1?"s":""} locked`,description:"Upgrade to Pro to unlock full event history"})}):null,initialNumToRender:10,maxToRenderPerBatch:10,windowSize:10})]})};const N=s&&s.events.length>1?(0,_jsxRuntime.jsx)(_StorageEventDetailContent.StorageEventDetailFooter,{conversation:s,selectedEventIndex:j,onEventIndexChange:h,applySafeAreaInset:R==="bottomSheet"}):y&&c!==null&&y.events.length>1?(0,_jsxRuntime.jsx)(_StorageEventDetailContent.StorageEventDetailFooter,{conversation:y,selectedEventIndex:c,onEventIndexChange:d,applySafeAreaInset:R==="bottomSheet"}):null;const Ae=x?()=>_(false):c!==null?()=>d(null):S?U:s?()=>{b(null);h(0)}:F;const re=x?(0,_jsxRuntime.jsxs)(_sharedUi.ModalHeader,{children:[(0,_jsxRuntime.jsx)(_sharedUi.ModalHeader.Navigation,{onBack:()=>_(false)}),(0,_jsxRuntime.jsx)(_sharedUi.ModalHeader.Content,{title:"Filters"})]}):S?(0,_jsxRuntime.jsxs)(_sharedUi.ModalHeader,{children:[(0,_jsxRuntime.jsx)(_sharedUi.ModalHeader.Navigation,{onBack:c!==null?()=>d(null):U}),(0,_jsxRuntime.jsx)(_sharedUi.ModalHeader.Content,{title:`${S} History`,centered:true})]}):s?(0,_jsxRuntime.jsxs)(_sharedUi.ModalHeader,{children:[(0,_jsxRuntime.jsx)(_sharedUi.ModalHeader.Navigation,{onBack:()=>{b(null);h(0)}}),(0,_jsxRuntime.jsx)(_sharedUi.ModalHeader.Content,{title:s.key})]}):B?(0,_jsxRuntime.jsxs)(_sharedUi.ModalHeader,{children:[(0,_jsxRuntime.jsx)(_sharedUi.ModalHeader.Navigation,{onBack:()=>k(null)}),(0,_jsxRuntime.jsx)(_sharedUi.ModalHeader.Content,{title:B.key,centered:true,testID:"buoy-storage-detail-title"})]}):(0,_jsxRuntime.jsxs)(_sharedUi.ModalHeader,{children:[F&&(0,_jsxRuntime.jsx)(_sharedUi.ModalHeader.Navigation,{onBack:F}),(0,_jsxRuntime.jsx)(_sharedUi.ModalHeader.Content,{title:"",children:P?(0,_jsxRuntime.jsx)(_sharedUi.SearchBar,{value:L,onChange:q,onClear:()=>{q("");M(false)},placeholder:"Search storage keys...",testID:"buoy-storage-search",autoFocus:true,onSubmitEditing:()=>M(false),returnKeyType:"search",containerStyle:styles.headerSearchContainer}):(0,_jsxRuntime.jsx)(_sharedUi.TabSelector,{tabs:[{key:"browser",label:"Storage"},{key:"events",label:`Events${i.length>0?` (${i.length})`:""}`}],activeTab:m,testIDPrefix:"buoy-storage-tab",onTabChange:e=>{le(e);D(null);d(null);b(null);h(0);k(null)}})}),(0,_jsxRuntime.jsxs)(_sharedUi.ModalHeader.Actions,{children:[z&&!P?(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{onPress:z,style:styles.iconButton,testID:"buoy-storage-refresh",accessibilityLabel:"Refresh storage",accessibilityRole:"button",children:(0,_jsxRuntime.jsx)(_sharedUi.RefreshCw,{size:14,color:_sharedUi.night.color.textSecondary})}):null,(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{onPress:me,testID:"buoy-storage-filters",accessibilityLabel:"Storage filters",accessibilityRole:"button",style:[styles.iconButton,(u.size>0||g.size<3)&&styles.activeFilterButton],children:(0,_jsxRuntime.jsx)(_sharedUi.Filter,{size:14,color:u.size>0||g.size<3?_sharedUi.night.color.accent:_sharedUi.night.color.textSecondary})}),m==="browser"&&!P&&(0,_jsxRuntime.jsxs)(_jsxRuntime.Fragment,{children:[(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{onPress:()=>M(true),testID:"buoy-storage-search-open",accessibilityLabel:"Open search",accessibilityRole:"button",style:styles.iconButton,children:(0,_jsxRuntime.jsx)(_sharedUi.Search,{size:14,color:_sharedUi.night.color.textSecondary})}),(0,_jsxRuntime.jsx)(_sharedUi.ToolbarCopyButton,{value:be,disabled:H.current.length===0,buttonStyle:styles.iconButton,testID:"buoy-storage-copy"})]}),m==="events"&&(0,_jsxRuntime.jsxs)(_jsxRuntime.Fragment,{children:[(0,_jsxRuntime.jsx)(_sharedUi.ToolbarCopyButton,{value:je,disabled:i.length===0,buttonStyle:styles.iconButton,testID:"buoy-storage-events-copy"}),(0,_jsxRuntime.jsx)(_sharedUi.PowerToggleButton,{isEnabled:Q,onToggle:Se,accessibilityLabel:"Toggle storage event monitoring",testID:"buoy-storage-power"}),(0,_jsxRuntime.jsx)(_sharedUi.ToolbarClearButton,{onPress:he,buttonStyle:styles.iconButton,testID:"buoy-storage-clear-events"})]})]})]});if(se){return(0,_jsxRuntime.jsx)(_sharedUi.TickProvider,{children:(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.inlineRoot,children:[(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.inlineHeader,..._sharedUi.windowDragProps,children:re}),te(),N]})})}return(0,_jsxRuntime.jsx)(_sharedUi.TickProvider,{children:(0,_jsxRuntime.jsx)(_sharedUi.JsModal,{visible:o,onClose:p,onBack:Ae,onMinimize:oe,persistenceKey:Me,header:{showToggleButton:true,customContent:re},onModeChange:pe,enablePersistence:true,initialMode:"bottomSheet",enableGlitchEffects:true,styles:{},footer:N,footerHeight:N?68:0,disableScrollWrapper:true,children:te()})})}function StorageToolView(o={}){return(0,_jsxRuntime.jsx)(StorageModalWithTabs,{...o,inline:true,visible:true,onClose:()=>{}})}const styles=_reactNative.StyleSheet.create({inlineRoot:{flex:1,minHeight:0,backgroundColor:"transparent"},inlineHeader:{paddingHorizontal:12,paddingVertical:8,borderBottomWidth:1,borderBottomColor:_sharedUi.macOSColors.border.default,backgroundColor:"transparent"},headerSearchContainer:{flex:1},flexFill:{flex:1},iconButton:{width:32,height:32,borderRadius:8,backgroundColor:_sharedUi.night.color.buttonSurface,borderWidth:1,borderColor:_sharedUi.night.color.border,alignItems:"center",justifyContent:"center"},activeFilterButton:{backgroundColor:_sharedUi.night.color.accentSoft,borderColor:_sharedUi.night.color.accentBorderStrong},separator:{height:8},listContent:{paddingVertical:6},lockedBannerContainer:{marginTop:8,marginHorizontal:16},eventFilterBar:{paddingHorizontal:12,paddingTop:8,paddingBottom:4},emptyState:{flex:1,justifyContent:"center",alignItems:"center",padding:32},emptyTitle:{color:_sharedUi.night.color.text,fontSize:16,fontWeight:"600",marginTop:16,marginBottom:8,fontFamily:_sharedUi.monoFont,letterSpacing:.5,textTransform:"uppercase"},emptySubtitle:{color:_sharedUi.night.color.textSecondary,fontSize:14,textAlign:"center",fontFamily:_sharedUi.monoFont},eventNavigation:{flexDirection:"row",alignItems:"center",gap:8,paddingHorizontal:8},navButton:{padding:4,borderRadius:4},navButtonDisabled:{opacity:.3},eventCounter:{color:_sharedUi.night.color.text,fontSize:12,fontWeight:"600",fontFamily:_sharedUi.monoFont,paddingHorizontal:8},headerTopRow:{flexDirection:"row",alignItems:"center",gap:8,marginBottom:12},keyNameContainer:{flex:1,flexDirection:"row",alignItems:"center",gap:6,backgroundColor:_sharedUi.night.color.surfaceElevated,paddingHorizontal:10,paddingVertical:4,borderRadius:6,borderWidth:1,borderColor:_sharedUi.night.color.border,height:28},keyNameText:{flex:1,fontSize:13,fontWeight:"600",color:_sharedUi.night.color.accent,fontFamily:_sharedUi.monoFont,letterSpacing:.5},contentWrapper:{flex:1}});
@@ -1 +1 @@
1
- "use strict";var _appAsyncStorage=_interopRequireDefault(require("./appAsyncStorage"));var _sharedUi=require("@buoy-gg/shared-ui");var _asyncStorageCompat=require("./asyncStorageCompat");var _clearAllStorage=require("./clearAllStorage");var _MMKVInstanceRegistry=require("./MMKVInstanceRegistry");var _mmkvTypeDetection=require("./mmkvTypeDetection");var _SecureStoreRegistry=require("./SecureStoreRegistry");function _interopRequireDefault(s){return s&&s.__esModule?s:{default:s}}function deleteMMKVKey(s,i){if(s.remove)s.remove(i);else s.delete?.(i)}function status(){return{canCapture:true,canRestore:true}}async function captureStorageData(){const s=[];const i=(await _appAsyncStorage.default.getAllKeys()).filter(o=>!(0,_sharedUi.isDevToolsStorageKey)(o));const a=(await(0,_asyncStorageCompat.readMany)(i)).filter(o=>o[1]!==null);const r={};for(const{id:o,instance:p}of _MMKVInstanceRegistry.mmkvInstanceRegistry.getAll().filter(({id:e})=>!(0,_sharedUi.isDevToolsStorageKey)(e))){try{r[o]=p.getAllKeys().filter(e=>!(0,_sharedUi.isDevToolsStorageKey)(e)).map(e=>{const{value:y,type:c}=(0,_mmkvTypeDetection.detectMMKVType)(p,e);if(c==="buffer"){s.push(`mmkv "${o}"/"${e}": ArrayBuffer value not capturable`)}return{key:e,value:y,valueType:c}})}catch{s.push(`mmkv "${o}": unreadable, captured without entries`);r[o]=[]}}const u={};const n=_SecureStoreRegistry.secureStoreRegistry.getModule();for(const{key:o,options:p}of _SecureStoreRegistry.secureStoreRegistry.getAll().filter(({key:e})=>!(0,_sharedUi.isDevToolsStorageKey)(e))){if(p.requireAuthentication){s.push(`secure "${o}": biometric-protected, not capturable`);continue}let e=null;if(n){try{e=await n.getItemAsync(o,p)}catch{s.push(`secure "${o}": unreadable, captured as unset`)}}u[o]=e}return{data:{async:a,mmkv:r,secure:u},warnings:s}}async function capture(){const{data:s,warnings:i}=await captureStorageData();return{data:s,warnings:i}}async function restore(s,i){const a=s;const r=(0,_sharedUi.createRestoreScope)(i);const u=r.touch;const n=(0,_sharedUi.emptyRestoreResult)();if(!a){return(0,_sharedUi.failedRestore)("empty storage snapshot")}try{const e=(a.async??[]).filter(([t])=>!(0,_sharedUi.isDevToolsStorageKey)(t)&&u(`async:${t}`));const y=new Set(e.map(([t])=>t));const c=(await _appAsyncStorage.default.getAllKeys()).filter(t=>!(0,_sharedUi.isDevToolsStorageKey)(t));const d=c.filter(t=>!y.has(t)&&u(`async:${t}`));r.countExcluded((a.async??[]).length-e.length);if(d.length>0)await(0,_asyncStorageCompat.removeMany)(d);if(e.length>0)await(0,_asyncStorageCompat.writeMany)(e);n.applied+=e.length+d.length}catch(e){n.ok=false;n.warnings.push(`asyncstorage restore failed: ${String(e)}`)}for(const[e,y]of Object.entries(a.mmkv??{})){if((0,_sharedUi.isDevToolsStorageKey)(e))continue;const c=_MMKVInstanceRegistry.mmkvInstanceRegistry.get(e);if(!c){n.skipped.push({id:`mmkv:${e}`,reason:"instance not registered"});continue}if(c.instance.isReadOnly){n.skipped.push({id:`mmkv:${e}`,reason:"instance registered read-only"});continue}const{instance:d}=c;try{const t=new Set(y.map(l=>l.key));const g=d.getAllKeys().filter(l=>!(0,_sharedUi.isDevToolsStorageKey)(l));for(const l of g){if(!r.allows(`mmkv:${e}/${l}`))continue;if(!t.has(l)){deleteMMKVKey(d,l);n.applied+=1}}for(const l of y){if((0,_sharedUi.isDevToolsStorageKey)(l.key))continue;if(!u(`mmkv:${e}/${l.key}`))continue;if(l.valueType==="buffer"){n.skipped.push({id:`mmkv:${e}/${l.key}`,reason:"ArrayBuffer values cannot be restored"});continue}d.set(l.key,l.value);n.applied+=1}}catch(t){n.ok=false;n.warnings.push(`mmkv "${e}" restore failed: ${String(t)}`)}}const o=a.secure??{};for(const{key:e,options:y}of _SecureStoreRegistry.secureStoreRegistry.getAll().filter(({key:c})=>!(0,_sharedUi.isDevToolsStorageKey)(c))){if(!r.allows(`secure:${e}`))continue;if(y.requireAuthentication){if(e in o){n.skipped.push({id:`secure:${e}`,reason:"biometric-protected keys are never written"})}continue}try{if(e in o){const c=o[e];if(c===null)await _SecureStoreRegistry.secureStoreRegistry.deleteValue(e);else await _SecureStoreRegistry.secureStoreRegistry.setValue(e,c)}else{await _SecureStoreRegistry.secureStoreRegistry.deleteValue(e)}n.applied+=1}catch(c){n.ok=false;n.warnings.push(`secure "${e}" restore failed: ${String(c)}`)}}for(const e of Object.keys(o)){if((0,_sharedUi.isDevToolsStorageKey)(e))continue;if(!u(`secure:${e}`))continue;if(!_SecureStoreRegistry.secureStoreRegistry.getAll().filter(({key:y})=>!(0,_sharedUi.isDevToolsStorageKey)(y)).some(y=>y.key===e)){n.skipped.push({id:`secure:${e}`,reason:"key no longer registered with registerSecureStoreKeys"})}}const p=r.excludedWarning("item(s)");if(p)n.warnings.push(p);return n}async function clear(){const s=(0,_sharedUi.emptyRestoreResult)();try{await(0,_clearAllStorage.clearAllAppStorage)();s.applied+=1}catch(i){s.ok=false;s.warnings.push(`asyncstorage clear failed: ${String(i)}`)}for(const{id:i,instance:a}of _MMKVInstanceRegistry.mmkvInstanceRegistry.getAll().filter(({id:r})=>!(0,_sharedUi.isDevToolsStorageKey)(r))){if(a.isReadOnly){s.skipped.push({id:`mmkv:${i}`,reason:"instance registered read-only"});continue}try{for(const r of a.getAllKeys().filter(u=>!(0,_sharedUi.isDevToolsStorageKey)(u))){deleteMMKVKey(a,r);s.applied+=1}}catch(r){s.ok=false;s.warnings.push(`mmkv "${i}" clear failed: ${String(r)}`)}}for(const{key:i,options:a}of _SecureStoreRegistry.secureStoreRegistry.getAll().filter(({key:r})=>!(0,_sharedUi.isDevToolsStorageKey)(r))){if(a.requireAuthentication){s.skipped.push({id:`secure:${i}`,reason:"biometric-protected keys are never written"});continue}try{await _SecureStoreRegistry.secureStoreRegistry.deleteValue(i);s.applied+=1}catch(r){s.ok=false;s.warnings.push(`secure "${i}" clear failed: ${String(r)}`)}}return s}const ITEM_RENDER_CHAR_LIMIT=256*1024;function classifyValue(s,i,a,r,u,n){return(0,_sharedUi.classifyPreviewItem)({key:s,label:i,oldValue:a,newValue:r,inOld:u,inNew:n},{equal:Object.is,tooLarge:o=>typeof o==="string"&&o.length>ITEM_RENDER_CHAR_LIMIT,tooLargeReason:"value too large to render a diff \u2014 restore still applies it"})}async function previewItems(s,i){const a=s??{async:[],mmkv:{},secure:{}};const r=i===void 0;const u=r?(await captureStorageData()).data:i??{async:[],mmkv:{},secure:{}};const n=[];const o=[];const p=new Map(u.async??[]);const e=new Map(a.async??[]);for(const t of(0,_sharedUi.unionKeys)(p,e)){if((0,_sharedUi.isDevToolsStorageKey)(t))continue;n.push(classifyValue(`async:${t}`,t,p.get(t),e.get(t),p.has(t),e.has(t)))}for(const t of(0,_sharedUi.unionKeys)(u.mmkv,a.mmkv)){if((0,_sharedUi.isDevToolsStorageKey)(t))continue;const g=r?_MMKVInstanceRegistry.mmkvInstanceRegistry.get(t):null;const l=r&&!g;const w=r&&g?.instance.isReadOnly===true;const m=new Map((u.mmkv?.[t]??[]).map(f=>[f.key,f]));const S=new Map((a.mmkv?.[t]??[]).map(f=>[f.key,f]));for(const f of(0,_sharedUi.unionKeys)(m,S)){if((0,_sharedUi.isDevToolsStorageKey)(f))continue;const K=`mmkv:${t}/${f}`;const $=`${t} \xB7 ${f}`;const k=m.get(f);const h=S.get(f);let v=classifyValue(K,$,k?.value,h?.value,m.has(f),S.has(f));if(l){v=(0,_sharedUi.wontApply)(v,"MMKV instance not registered")}else if(w){v=(0,_sharedUi.wontApply)(v,"MMKV instance registered read-only")}else if(h?.valueType==="buffer"||k?.valueType==="buffer"){v=(0,_sharedUi.wontApply)(v,"ArrayBuffer values cannot be restored")}n.push(v)}}const y=u.secure??{};const c=a.secure??{};const d=r?new Map(_SecureStoreRegistry.secureStoreRegistry.getAll().filter(({key:t})=>!(0,_sharedUi.isDevToolsStorageKey)(t)).map(t=>[t.key,t])):null;for(const t of(0,_sharedUi.unionKeys)(y,c)){if((0,_sharedUi.isDevToolsStorageKey)(t))continue;let g=classifyValue(`secure:${t}`,t,y[t],c[t],t in y,t in c);if(r){const l=d?.get(t);if(!l){g=(0,_sharedUi.wontApply)(g,"key no longer registered with registerSecureStoreKeys")}else if(l.options.requireAuthentication){g=(0,_sharedUi.wontApply)(g,"biometric-protected keys are never written")}}n.push(g)}return{items:n,notes:o}}(0,_sharedUi.registerStateSnapshotProvider)({id:"storage",label:"Storage",status,capture,restore,clear,previewItems});
1
+ "use strict";var _appAsyncStorage=_interopRequireDefault(require("./appAsyncStorage"));var _sharedUi=require("@buoy-gg/shared-ui");var _asyncStorageCompat=require("./asyncStorageCompat");var _clearAllStorage=require("./clearAllStorage");var _MMKVInstanceRegistry=require("./MMKVInstanceRegistry");var _mmkvTypeDetection=require("./mmkvTypeDetection");var _SecureStoreRegistry=require("./SecureStoreRegistry");function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function deleteMMKVKey(e,n){if(e.remove)e.remove(n);else e.delete?.(n)}function status(){return{canCapture:true,canRestore:true}}async function captureStorageData(){const e=[];const n=(await _appAsyncStorage.default.getAllKeys()).filter(t=>!(0,_sharedUi.isDevToolsStorageKey)(t));const i=(await(0,_asyncStorageCompat.readMany)(n)).filter(t=>t[1]!==null);const o={};for(const{id:t,instance:l}of _MMKVInstanceRegistry.mmkvInstanceRegistry.getAll().filter(({id:u})=>!(0,_sharedUi.isDevToolsStorageKey)(u))){try{o[t]=l.getAllKeys().filter(u=>!(0,_sharedUi.isDevToolsStorageKey)(u)).map(u=>{const{value:m,type:r}=(0,_mmkvTypeDetection.detectMMKVType)(l,u);if(r==="buffer"){e.push(`mmkv "${t}"/"${u}": ArrayBuffer value not capturable`)}return{key:u,value:m,valueType:r}})}catch{e.push(`mmkv "${t}": unreadable, captured without entries`);o[t]=[]}}const c={};const a=_SecureStoreRegistry.secureStoreRegistry.getModule();for(const{key:t,options:l}of _SecureStoreRegistry.secureStoreRegistry.getAll().filter(({key:u})=>!(0,_sharedUi.isDevToolsStorageKey)(u))){if(l.requireAuthentication){e.push(`secure "${t}": biometric-protected, not capturable`);continue}let u=null;if(a){try{u=await a.getItemAsync(t,l)}catch{e.push(`secure "${t}": unreadable, captured as unset`)}}c[t]=u}return{data:{async:i,mmkv:o,secure:c},warnings:e}}function mmkvInstanceRef(e){return`mmkv:${e.replace(/%/g,"%25").replace(/\//g,"%2F")}`}function mmkvItemId(e,n){return`${mmkvInstanceRef(e)}/${n}`}function withCurrentMmkvIds(e,n){if(!e)return void 0;const i=Object.keys(n).filter(a=>mmkvInstanceRef(a)!==`mmkv:${a}`);if(i.length===0)return[...e];const o=new Set(Object.entries(n).flatMap(([a,t])=>t.map(l=>mmkvItemId(a,l.key))));const c=new Set(e);for(const a of e){if(o.has(a))continue;for(const t of i){const l=`mmkv:${t}/`;if(a.startsWith(l))c.add(mmkvItemId(t,a.slice(l.length)))}}return[...c]}async function capture(){const{data:e,warnings:n}=await captureStorageData();return{data:e,warnings:n}}async function restore(e,n){const i=e;const o=i?.mmkv??{};const c=(0,_sharedUi.createRestoreScope)({excludeKeys:withCurrentMmkvIds(n?.excludeKeys,o),includeKeys:withCurrentMmkvIds(n?.includeKeys,o)});const a=c.touch;const t=(0,_sharedUi.emptyRestoreResult)();if(!i){return(0,_sharedUi.failedRestore)("empty storage snapshot")}try{const r=(i.async??[]).filter(([y])=>!(0,_sharedUi.isDevToolsStorageKey)(y)&&a(`async:${y}`));const d=new Set(r.map(([y])=>y));const s=(await _appAsyncStorage.default.getAllKeys()).filter(y=>!(0,_sharedUi.isDevToolsStorageKey)(y));const p=s.filter(y=>!d.has(y)&&a(`async:${y}`));c.countExcluded((i.async??[]).length-r.length);if(p.length>0)await(0,_asyncStorageCompat.removeMany)(p);if(r.length>0)await(0,_asyncStorageCompat.writeMany)(r);t.applied+=r.length+p.length}catch(r){t.ok=false;t.warnings.push(`asyncstorage restore failed: ${String(r)}`)}for(const[r,d]of Object.entries(i.mmkv??{})){if((0,_sharedUi.isDevToolsStorageKey)(r))continue;const s=_MMKVInstanceRegistry.mmkvInstanceRegistry.get(r);if(!s){t.skipped.push({id:mmkvInstanceRef(r),reason:"instance not registered"});continue}if(s.instance.isReadOnly){t.skipped.push({id:mmkvInstanceRef(r),reason:"instance registered read-only"});continue}const{instance:p}=s;try{const y=new Set(d.map(f=>f.key));const S=p.getAllKeys().filter(f=>!(0,_sharedUi.isDevToolsStorageKey)(f));for(const f of S){if(!c.allows(mmkvItemId(r,f)))continue;if(!y.has(f)){deleteMMKVKey(p,f);t.applied+=1}}for(const f of d){if((0,_sharedUi.isDevToolsStorageKey)(f.key))continue;if(!a(mmkvItemId(r,f.key)))continue;if(f.valueType==="buffer"){t.skipped.push({id:mmkvItemId(r,f.key),reason:"ArrayBuffer values cannot be restored"});continue}p.set(f.key,f.value);t.applied+=1}}catch(y){t.ok=false;t.warnings.push(`mmkv "${r}" restore failed: ${String(y)}`)}}const l=i.secure??{};const u=i.secure===void 0;for(const{key:r,options:d}of u?[]:_SecureStoreRegistry.secureStoreRegistry.getAll().filter(({key:s})=>!(0,_sharedUi.isDevToolsStorageKey)(s))){if(!c.allows(`secure:${r}`))continue;if(d.requireAuthentication){if(r in l){t.skipped.push({id:`secure:${r}`,reason:"biometric-protected keys are never written"})}continue}try{if(r in l){const s=l[r];if(s===null)await _SecureStoreRegistry.secureStoreRegistry.deleteValue(r);else await _SecureStoreRegistry.secureStoreRegistry.setValue(r,s)}else{await _SecureStoreRegistry.secureStoreRegistry.deleteValue(r)}t.applied+=1}catch(s){t.ok=false;t.warnings.push(`secure "${r}" restore failed: ${String(s)}`)}}for(const r of Object.keys(l)){if((0,_sharedUi.isDevToolsStorageKey)(r))continue;if(!a(`secure:${r}`))continue;if(!_SecureStoreRegistry.secureStoreRegistry.getAll().filter(({key:d})=>!(0,_sharedUi.isDevToolsStorageKey)(d)).some(d=>d.key===r)){t.skipped.push({id:`secure:${r}`,reason:"key no longer registered with registerSecureStoreKeys"})}}const m=c.excludedWarning("item(s)");if(m)t.warnings.push(m);return t}async function clear(){const e=(0,_sharedUi.emptyRestoreResult)();try{await(0,_clearAllStorage.clearAllAppStorage)();e.applied+=1}catch(n){e.ok=false;e.warnings.push(`asyncstorage clear failed: ${String(n)}`)}for(const{id:n,instance:i}of _MMKVInstanceRegistry.mmkvInstanceRegistry.getAll().filter(({id:o})=>!(0,_sharedUi.isDevToolsStorageKey)(o))){if(i.isReadOnly){e.skipped.push({id:mmkvInstanceRef(n),reason:"instance registered read-only"});continue}try{for(const o of i.getAllKeys().filter(c=>!(0,_sharedUi.isDevToolsStorageKey)(c))){deleteMMKVKey(i,o);e.applied+=1}}catch(o){e.ok=false;e.warnings.push(`mmkv "${n}" clear failed: ${String(o)}`)}}for(const{key:n,options:i}of _SecureStoreRegistry.secureStoreRegistry.getAll().filter(({key:o})=>!(0,_sharedUi.isDevToolsStorageKey)(o))){if(i.requireAuthentication){e.skipped.push({id:`secure:${n}`,reason:"biometric-protected keys are never written"});continue}try{await _SecureStoreRegistry.secureStoreRegistry.deleteValue(n);e.applied+=1}catch(o){e.ok=false;e.warnings.push(`secure "${n}" clear failed: ${String(o)}`)}}return e}const ITEM_RENDER_CHAR_LIMIT=256*1024;function classifyValue(e,n,i,o,c,a){return(0,_sharedUi.classifyPreviewItem)({key:e,label:n,oldValue:i,newValue:o,inOld:c,inNew:a},{equal:Object.is,tooLarge:t=>typeof t==="string"&&t.length>ITEM_RENDER_CHAR_LIMIT,tooLargeReason:"value too large to render a diff \u2014 restore still applies it"})}async function previewItems(e,n){const i=e??{async:[],mmkv:{},secure:{}};const o=n===void 0;const c=o?(await captureStorageData()).data:n??{async:[],mmkv:{},secure:{}};const a=[];const t=[];const l=new Map(c.async??[]);const u=new Map(i.async??[]);for(const s of(0,_sharedUi.unionKeys)(l,u)){if((0,_sharedUi.isDevToolsStorageKey)(s))continue;a.push(classifyValue(`async:${s}`,s,l.get(s),u.get(s),l.has(s),u.has(s)))}for(const s of(0,_sharedUi.unionKeys)(c.mmkv,i.mmkv)){if((0,_sharedUi.isDevToolsStorageKey)(s))continue;const p=o?_MMKVInstanceRegistry.mmkvInstanceRegistry.get(s):null;const y=o&&!p;const S=o&&p?.instance.isReadOnly===true;const f=new Map((c.mmkv?.[s]??[]).map(g=>[g.key,g]));const h=new Map((i.mmkv?.[s]??[]).map(g=>[g.key,g]));for(const g of(0,_sharedUi.unionKeys)(f,h)){if((0,_sharedUi.isDevToolsStorageKey)(g))continue;const K=mmkvItemId(s,g);const R=`${s} \xB7 ${g}`;const k=f.get(g);const w=h.get(g);let v=classifyValue(K,R,k?.value,w?.value,f.has(g),h.has(g));if(y){v=(0,_sharedUi.wontApply)(v,"MMKV instance not registered")}else if(S){v=(0,_sharedUi.wontApply)(v,"MMKV instance registered read-only")}else if(w?.valueType==="buffer"||k?.valueType==="buffer"){v=(0,_sharedUi.wontApply)(v,"ArrayBuffer values cannot be restored")}a.push(v)}}const m=c.secure??{};const r=i.secure??{};const d=o?new Map(_SecureStoreRegistry.secureStoreRegistry.getAll().filter(({key:s})=>!(0,_sharedUi.isDevToolsStorageKey)(s)).map(s=>[s.key,s])):null;for(const s of(0,_sharedUi.unionKeys)(m,r)){if((0,_sharedUi.isDevToolsStorageKey)(s))continue;let p=classifyValue(`secure:${s}`,s,m[s],r[s],s in m,s in r);if(o){const y=d?.get(s);if(!y){p=(0,_sharedUi.wontApply)(p,"key no longer registered with registerSecureStoreKeys")}else if(y.options.requireAuthentication){p=(0,_sharedUi.wontApply)(p,"biometric-protected keys are never written")}}a.push(p)}return{items:a,notes:t}}(0,_sharedUi.registerStateSnapshotProvider)({id:"storage",label:"Storage",status,capture,restore,clear,previewItems});
@@ -1,4 +1,4 @@
1
1
  "use strict";import{storageLabels as wt}from"../utils/storageLabels";import{useMemo as S,useCallback as b,useState as N,useEffect as A,useRef as ie}from"react";import{StyleSheet as It,Text as m,View as f,TouchableOpacity as ae,ScrollView as Re,Alert as le}from"react-native";import{absoluteFill as Ae,useLimit as Ee,TIER_LIMITS as _t,monoFont as W}from"@buoy-gg/shared-ui";import{Database as Le,Zap as Mt,ProBadge as ze,ProUpgradeModal as Kt,ToolEmptyState as xt,resolveListEmptyState as Bt}from"@buoy-gg/shared-ui";import{isDevToolsStorageKey as h}from"@buoy-gg/shared-ui";import{StorageKeySection as Nt,storageRowId as De}from"./StorageKeySection";import{StorageKeyDetailScreen as qt}from"./StorageKeyDetailScreen";import{StorageFilterCards as Vt}from"./StorageFilterCards";import{useAsyncStorageKeys as Rt}from"../hooks/useAsyncStorageKeys";import{addListener as At}from"../utils/AsyncStorageListener";import{useMultiMMKVKeys as Et}from"../hooks/useMMKVKeys";import{useSecureStoreKeys as Lt}from"../hooks/useSecureStoreKeys";import{useMMKVInstances as zt}from"../hooks/useMMKVInstances";import{StorageSaveNotice as Dt}from"./StorageSaveNotice";import{StorageActionButtons as Ft}from"./StorageActionButtons";import{SelectionActionBar as Wt}from"./SelectionActionBar";import{addMMKVListener as Ot}from"../utils/MMKVListener";import{onStorageBrowserRefresh as Ht}from"../utils/storageBrowserRefresh";import{deleteStorageKeys as Pt}from"../utils/deleteStorageKeys";import{setStorageValue as $t,storageEditBlockedReason as Ut}from"../utils/setStorageValue";import{gameUIColors as E,macOSColors as J,night as s,HardDrive as Fe}from"@buoy-gg/shared-ui";import{useIsPro as jt}from"@buoy-gg/license";import{jsx as a,jsxs as d,Fragment as Gt}from"react/jsx-runtime";const We=[J.semantic.info,J.semantic.success,J.semantic.warning,J.semantic.debug,"#FF6B9D","#00D9FF"];function L(z){const ce=z.split("").reduce((O,de)=>O+de.charCodeAt(0),0);return We[ce%We.length]}export const FREE_TIER_KEY_LIMIT=_t["storage.keys"].free;export function GameUIStorageBrowser({requiredStorageKeys:z=[],showFilters:ce=false,ignoredPatterns:O=new Set(["@react_buoy"]),onTogglePattern:de,onAddPattern:ue,searchQuery:w="",storageDataRef:X,eventCountByKey:ge,lastWriteByKey:Yt,onViewHistory:Z,enabledStorageTypes:H,statusFilter:ye,onStatusFilterChange:me,onStatusCountsChange:fe,pinnedKeys:_,onTogglePin:he,storageTypeFilter:pe,onStorageTypeFilterChange:Se,applySafeAreaInset:Oe,detailKey:P=null,onOpenKey:He,onCloseDetail:be}){const M=jt();const $=Ee("storage.keys");const Ce=Ee("storage.mmkvInstances");const[Q,q]=N(false);A(()=>{if(Q&&M){q(false)}},[Q,M]);const[Pe,$e]=N("all");const ee=ye!=null&&me!=null;const T=ee?ye:Pe;const Ue=ee?me:$e;const[je,Ge]=N("all");const ve=pe!=null&&Se!=null;const C=ve?pe:je;const Ye=ve?Se:Ge;const[g,Te]=N(null);const Je=ie(null);const Xe=ie(0);const ke=ie(new Map);const Ze=b((e,t)=>{if(t)ke.current.set(e,t);else ke.current.delete(e)},[]);const[we,Ie]=N(0);const[te,re]=N(false);const[U,V]=N(new Set);const{instances:y}=zt(false);const{storageKeys:_e,isLoading:Qe,error:et,refresh:j}=Rt(z);const tt=S(()=>y.map(e=>({instance:e.instance,id:e.id})),[y]);const{storageKeys:oe,isLoading:rt,error:ot,refresh:G}=Et(tt,z);const Me=S(()=>{if(!g){return oe}return oe.filter(e=>e.instanceId===g)},[oe,g]);const{storageKeys:Ke,isLoading:nt,error:st,refresh:xe}=Lt(z);const c=S(()=>{return[..._e,...Me,...Ke].filter(e=>!h(e.key))},[_e,Me,Ke]);const K=S(()=>{if(!P)return null;const e=De(P);return c.find(t=>De(t)===e)??P},[P,c]);const it=Qe||rt||nt;const Be=et||ot||st;const k=b(()=>{j();G();xe()},[j,G,xe]);const R=b(e=>{return e.instanceId?`${e.storageType}-${e.instanceId}-${e.key}`:`${e.storageType}-${e.key}`},[]);const at=b(()=>{re(e=>{if(e){V(new Set)}return!e})},[]);const lt=b((e,t)=>{const r=R(e);V(p=>{const i=new Set(p);if(t){i.add(r)}else{i.delete(r)}return i})},[R]);const ct=b(()=>{V(new Set);re(false);k()},[k]);const ne=b(e=>{e.forEach(t=>ue?.(t.key));V(new Set);re(false)},[ue]);const se=b(async(e,t)=>{if(!M){q(true);throw new Error("Editing storage values is a Pro feature.")}await $t(e,t,y);k();Ie(r=>r+1)},[M,y,k]);const dt=b(e=>{void se(e,JSON.stringify(!e.value)).catch(t=>{le.alert("Couldn't save",t instanceof Error?t.message:String(t))})},[se]);const Ne=b((e,t)=>{if(!M){q(true);return}le.alert("Delete key",`Delete "${e.key}"? This cannot be undone.`,[{text:"Cancel",style:"cancel"},{text:"Delete",style:"destructive",onPress:async()=>{try{await Pt([e],y.map(r=>({id:r.id,instance:r.instance})));k();t?.()}catch(r){le.alert("Error",`Failed to delete key: ${r}`)}}}])},[M,y,k]);const qe=b(e=>Ut(e,y),[y]);const ut=S(()=>{const e=c;const t={valid:e.filter(l=>l.status==="required_present"||l.status==="optional_present").length,missing:e.filter(l=>l.status==="required_missing").length,issues:e.filter(l=>l.status==="required_wrong_value"||l.status==="required_wrong_type").length,total:e.length};const r=e.filter(l=>l.storageType==="async");const p=e.filter(l=>l.storageType==="mmkv");const i=e.filter(l=>l.storageType==="secure");return{summary:{valid:t.valid,missing:t.missing,issues:t.issues,total:t.total,timestamp:new Date().toISOString()},asyncStorage:r.reduce((l,u)=>{l[u.key]=u.value;return l},{}),mmkv:p.reduce((l,u)=>{const I=u.instanceId||"default";if(!l[I])l[I]={};l[I][u.key]=u.value;return l},{}),secure:i.reduce((l,u)=>{l[u.key]=u.value;return l},{})}},[c]);A(()=>{if(X){X.current=c}},[c,X]);A(()=>{let e;const t=At(r=>{clearTimeout(e);e=setTimeout(()=>{j()},100)});return()=>{clearTimeout(e);t()}},[j]);A(()=>{let e;const t=Ht(()=>{clearTimeout(e);e=setTimeout(k,100)});return()=>{clearTimeout(e);t()}},[k]);A(()=>{let e;const t=Ot(r=>{const p=g===null||r.instanceId===g;if(p){clearTimeout(e);e=setTimeout(()=>{G()},100)}});return()=>{clearTimeout(e);t()}},[G,g]);const D=S(()=>{const e=c;const t=e.filter(i=>!h(i.key));const r=e.filter(i=>h(i.key));const p={totalCount:e.length,requiredCount:t.filter(i=>i.category==="required").length,missingCount:t.filter(i=>i.status==="required_missing").length,wrongValueCount:t.filter(i=>i.status==="required_wrong_value").length,wrongTypeCount:t.filter(i=>i.status==="required_wrong_type").length,presentRequiredCount:t.filter(i=>i.status==="required_present").length,optionalCount:t.filter(i=>i.category==="optional").length,mmkvCount:e.filter(i=>i.storageType==="mmkv").length,asyncCount:e.filter(i=>i.storageType==="async").length,secureCount:e.filter(i=>i.storageType==="secure").length,devToolsCount:r.length};return p},[c]);const x=S(()=>{let e=c.filter(o=>!h(o.key));if(C!=="all"){e=e.filter(o=>o.storageType===C)}const t=e.filter(o=>o.status==="required_present"||o.status==="optional_present").length;const r=e.filter(o=>o.status==="required_missing").length;const p=e.filter(o=>o.status==="required_wrong_type"||o.status==="required_wrong_value").length;let i=0;let l=0;let u=0;let I=0;if(T==="all"){i=c.filter(o=>!h(o.key)&&o.storageType==="async"&&(o.status==="required_present"||o.status==="optional_present")).length;l=c.filter(o=>!h(o.key)&&o.storageType==="mmkv"&&(o.status==="required_present"||o.status==="optional_present")).length;u=c.filter(o=>!h(o.key)&&o.storageType==="secure"&&(o.status==="required_present"||o.status==="optional_present")).length;I=i+l+u}else if(T==="missing"){i=c.filter(o=>!h(o.key)&&o.storageType==="async"&&o.status==="required_missing").length;l=c.filter(o=>!h(o.key)&&o.storageType==="mmkv"&&o.status==="required_missing").length;u=c.filter(o=>!h(o.key)&&o.storageType==="secure"&&o.status==="required_missing").length;I=i+l+u}else if(T==="issues"){i=c.filter(o=>!h(o.key)&&o.storageType==="async"&&(o.status==="required_wrong_type"||o.status==="required_wrong_value")).length;l=c.filter(o=>!h(o.key)&&o.storageType==="mmkv"&&(o.status==="required_wrong_type"||o.status==="required_wrong_value")).length;u=c.filter(o=>!h(o.key)&&o.storageType==="secure"&&(o.status==="required_wrong_type"||o.status==="required_wrong_value")).length;I=i+l+u}return{validCount:t,missingCount:r,issuesCount:p,asyncCount:i,mmkvCount:l,secureCount:u,totalCount:I}},[c,T,C]);A(()=>{fe?.({validCount:x.validCount,missingCount:x.missingCount,issuesCount:x.issuesCount})},[fe,x.validCount,x.missingCount,x.issuesCount]);const Ve=S(()=>{return[...c].sort((e,t)=>{const r={required_missing:1,required_wrong_type:2,required_wrong_value:3,required_present:4,optional_present:5};return(r[e.status]||999)-(r[t.status]||999)})},[c]);const Jt=S(()=>{return Array.from(new Set(c.map(e=>e.key))).sort()},[c]);const v=S(()=>{let e=Ve;if(H&&H.size>0){e=e.filter(t=>H.has(t.storageType))}e=e.filter(t=>{const r=Array.from(O).some(p=>t.key.includes(p));return!r});if(w){const t=w.toLowerCase();e=e.filter(r=>r.key.toLowerCase().includes(t))}switch(T){case"all":e=e.filter(t=>t.status==="required_present"||t.status==="optional_present");break;case"missing":e=e.filter(t=>t.status==="required_missing");break;case"issues":e=e.filter(t=>t.status==="required_wrong_type"||t.status==="required_wrong_value");break}if(C!=="all"){e=e.filter(t=>t.storageType===C)}if(_&&_.size>0){const t=e.filter(p=>_.has(p.key));const r=e.filter(p=>!_.has(p.key));e=[...t,...r]}return e},[Ve,T,C,O,w,g,H,_]);const B=S(()=>v.slice(0,$),[v,$]);const Y=S(()=>{return Math.max(0,v.length-$)},[v.length,$]);const gt=Y>0;const Xt=S(()=>{const e=v.filter(r=>!h(r.key));const t={totalCount:v.length,requiredCount:e.filter(r=>r.category==="required").length,missingCount:e.filter(r=>r.status==="required_missing").length,wrongValueCount:e.filter(r=>r.status==="required_wrong_value").length,wrongTypeCount:e.filter(r=>r.status==="required_wrong_type").length,presentRequiredCount:e.filter(r=>r.status==="required_present").length,optionalCount:e.filter(r=>r.category==="optional").length,mmkvCount:v.filter(r=>r.storageType==="mmkv").length,asyncCount:v.filter(r=>r.storageType==="async").length,secureCount:v.filter(r=>r.storageType==="secure").length,devToolsCount:v.filter(r=>h(r.key)).length};return t},[v]);const yt=S(()=>{return B.filter(e=>U.has(R(e)))},[B,U,R]);const mt=b(()=>{const e=new Set(B.map(R));V(e)},[B,R]);const ft=b(()=>{V(new Set)},[]);const F=D.requiredCount>0?Math.round(D.presentRequiredCount/D.requiredCount*100):D.totalCount>0?100:0;const ht=F>=90?"OPTIMAL":F>=70?"WARNING":"CRITICAL";const pt=F>=90?E.success:F>=70?E.warning:E.error;if(K){return a(f,{style:n.root,children:a(qt,{storageKey:K,editBlockedReason:qe(K),eventCount:ge?.[K.key],onSave:e=>se(K,e),onViewHistory:Z?()=>Z(K.key):void 0,onDeleteKey:e=>Ne(e,()=>be?.()),onHideKey:e=>{ne([e]);be?.()},isPinned:_?.has(K.key)??false,onTogglePin:he,applySafeAreaInset:Oe})})}if(it&&c.length===0){return d(f,{style:n.emptyState,children:[a(Le,{size:48,color:s.color.textTertiary}),a(m,{style:n.emptyTitle,children:"Loading storage keys..."})]})}if(Be){return d(f,{style:n.emptyState,children:[a(Le,{size:48,color:E.error}),a(m,{style:[n.emptyTitle,{color:E.error}],children:"Error loading storage"}),a(m,{style:n.emptySubtitle,children:Be.message})]})}const St=d(Gt,{children:[C==="mmkv"&&y.length===0&&d(f,{style:n.emptyMMKVState,children:[a(m,{style:n.emptyMMKVTitle,children:"No MMKV Instances Detected"}),a(m,{style:n.emptyMMKVSubtitle,children:"MMKV instances must be registered with registerMMKVInstance()"}),a(m,{style:n.emptyMMKVCode,children:`import { registerMMKVInstance } from '@buoy-gg/storage';
2
2
 
3
3
  const storage = createMMKV();
4
- registerMMKVInstance('mmkv.default', storage);`})]}),C==="mmkv"&&y.length>0&&d(f,{style:n.instanceNavbar,children:[d(f,{style:n.instanceNavbarHeader,children:[a(m,{style:n.instanceNavbarLabel,children:"INSTANCES"}),y.length>Ce&&a(ze,{style:{transform:[{scale:.85}]}})]}),d(Re,{horizontal:true,showsHorizontalScrollIndicator:false,contentContainerStyle:n.instanceNavbarScroll,children:[(M||y.length===1)&&d(ae,{onPress:()=>Te(null),testID:"buoy-storage-instance-all",accessibilityRole:"button",accessibilityLabel:`All ${wt.mmkv} instances`,style:[n.instanceNavbarButton,g===null&&n.instanceNavbarButtonActive],children:[a(Fe,{size:12,color:g===null?s.color.text:s.color.textSecondary}),a(m,{style:[n.instanceNavbarButtonText,g===null&&n.instanceNavbarButtonTextActive],children:"All"}),a(f,{style:n.instanceNavbarBadge,children:a(m,{style:n.instanceNavbarBadgeText,children:y.reduce((e,t)=>e+t.keyCount,0)})})]}),y.map((e,t)=>{const r=t>=Ce;return d(ae,{testID:`buoy-storage-instance-${e.id}`,accessibilityRole:"button",accessibilityLabel:`MMKV instance ${e.id}`,onPress:()=>{if(r){q(true)}else{Te(e.id)}},style:[n.instanceNavbarButton,e.id===g&&n.instanceNavbarButtonActive,{borderColor:r?s.color.border:L(e.id)+"40",backgroundColor:e.id===g?L(e.id)+"20":s.color.surfaceElevated,opacity:r?.5:1}],children:[a(Fe,{size:12,color:e.id===g?L(e.id):s.color.textSecondary}),a(m,{style:[n.instanceNavbarButtonText,e.id===g&&{color:L(e.id),fontWeight:"700"}],children:e.id}),a(f,{style:[n.instanceNavbarBadge,e.id===g&&{backgroundColor:L(e.id)+"30"}],children:a(m,{style:[n.instanceNavbarBadgeText,e.id===g&&{color:L(e.id)}],children:e.keyCount})})]},e.id)})]})]})]});const bt=a(Ft,{copyValue:ut,mmkvInstances:y.map(e=>({id:e.id,instance:e.instance})),activeStorageType:C,onClearComplete:k,isSelectMode:te,onToggleSelectMode:at,selectedCount:U.size});const Ct=te?a(Wt,{selectedKeys:yt,mmkvInstances:y.map(e=>({id:e.id,instance:e.instance})),onDeleteComplete:ct,onHideKeys:ne,onSelectAll:mt,onClearSelection:ft,totalVisibleKeys:B.length}):null;const vt=gt?d(ae,{style:n.limitBanner,onPress:()=>q(true),activeOpacity:.8,testID:"buoy-storage-locked-banner",accessibilityRole:"button",children:[d(f,{style:n.limitBannerContent,children:[d(f,{style:n.limitBannerLeft,children:[a(Mt,{size:16,color:s.color.accent}),a(m,{style:n.limitBannerText,children:w?`${Y} matching ${Y===1?"key":"keys"} in locked storage`:`${Y} keys locked`})]}),a(ze,{})]}),a(m,{style:n.limitBannerSubtext,children:w?"Upgrade to Pro to search your full storage":"Upgrade to Pro to unlock full storage access"})]}):null;const Tt=(()=>{const e=c.some(r=>!h(r.key));let t;if(w||!e){t=Bt({subject:"keys",verb:"registered",search:w,total:e?1:0,waiting:{otto:"empty",title:"No storage keys",message:"Nothing is registered for this tool to read."}});if(w&&e){t={...t,message:"No keys match. Clear the search to see them."}}}else if(T==="missing"){t={otto:"thumbsup",title:"No missing keys",message:"All required keys are present"}}else if(T==="issues"){t={otto:"cool",title:"No issues found",message:"All storage keys are correctly configured"}}else{t={otto:"broken",title:"No valid keys found",message:"All keys have issues or are missing"}}return a(xt,{...t,testID:"buoy-storage-keys-empty"})})();const kt=a(Kt,{visible:Q,onClose:()=>q(false),featureName:"Storage Keys"});return d(f,{style:n.root,children:[we>0?a(Dt,{onDone:()=>Ie(0)},we):null,d(Re,{testID:"buoy-storage-scroll",ref:Je,onScroll:e=>{Xe.current=e.nativeEvent.contentOffset.y},scrollEventThrottle:32,style:n.scrollContainer,contentContainerStyle:n.container,showsVerticalScrollIndicator:false,children:[a(f,{style:n.backgroundGrid}),a(Vt,{stats:D,tabStats:x,healthPercentage:F,healthStatus:ht,healthColor:pt,activeFilter:T,onFilterChange:Ue,activeStorageType:C,onStorageTypeChange:Ye,showStatus:!ee}),St,v.length>0?d(f,{style:n.keysSection,children:[d(f,{style:n.sectionHeader,children:[d(f,{style:n.sectionHeaderLeft,children:[d(m,{style:n.sectionTitle,children:[T==="all"?"KEYS":T==="missing"?"MISSING KEYS":"ISSUES TO FIX",C!=="all"&&` (${C.toUpperCase()})`]}),a(f,{style:n.countBadge,children:a(m,{style:n.countText,children:B.length})})]}),bt]}),Ct,a(Nt,{title:"",count:-1,keys:B,emptyMessage:"",isSelectMode:te,selectedKeys:U,onSelectionChange:lt,eventCountByKey:ge,onViewHistory:Z,onHideKey:e=>ne([e]),onToggleKey:dt,onDeleteKey:Ne,editBlockedFor:qe,pinnedKeys:_,onTogglePin:he,onRowRef:Ze,onOpenKey:He}),vt]}):Tt,a(m,{style:n.techFooter,children:"ASYNC STORAGE | MMKV | SECURE STORAGE BACKENDS"}),kt]})]})}const n=It.create({root:{flex:1,minHeight:0},editorOverlay:{...Ae,zIndex:10},scrollContainer:{flex:1,backgroundColor:"transparent"},container:{padding:12,paddingBottom:120},backgroundGrid:{...Ae,opacity:.006,backgroundColor:E.info},techFooter:{fontSize:8,color:s.color.textTertiary,fontFamily:W,textAlign:"center",marginTop:20,letterSpacing:1,opacity:.5},keysSection:{marginTop:8,backgroundColor:s.color.bg,borderRadius:12,padding:12,borderWidth:1,borderColor:s.color.border},sectionHeader:{flexDirection:"row",justifyContent:"space-between",alignItems:"center",marginBottom:10,paddingBottom:6,borderBottomWidth:1,borderBottomColor:s.color.separator},sectionHeaderLeft:{flexDirection:"row",alignItems:"center",gap:8},sectionTitle:{fontSize:12,fontWeight:"600",color:s.color.textSecondary,letterSpacing:.4,textTransform:"uppercase"},countBadge:{backgroundColor:s.color.surfaceElevated,paddingHorizontal:8,paddingVertical:3,borderRadius:6,borderWidth:1,borderColor:s.color.border},countText:{fontSize:11,fontWeight:"600",color:s.color.text,fontFamily:W},emptyState:{alignItems:"center",justifyContent:"center",paddingVertical:48},emptyTitle:{fontSize:16,fontWeight:"600",color:s.color.text,marginTop:12,marginBottom:8},emptySubtitle:{fontSize:13,color:s.color.textSecondary,textAlign:"center"},emptyMMKVState:{backgroundColor:s.color.surface,borderRadius:12,padding:20,borderWidth:1,borderColor:s.color.border,marginTop:8,alignItems:"center"},emptyMMKVTitle:{fontSize:14,fontWeight:"600",color:s.color.text,marginBottom:6},emptyMMKVSubtitle:{fontSize:12,color:s.color.textSecondary,textAlign:"center",marginBottom:12},emptyMMKVCode:{fontSize:10,fontFamily:W,color:s.color.accent,backgroundColor:s.color.bg,padding:12,borderRadius:8,borderWidth:1,borderColor:s.color.border,alignSelf:"stretch"},instanceNavbar:{marginTop:12,marginBottom:8,backgroundColor:s.color.surface,borderRadius:10,borderWidth:1,borderColor:s.color.border,padding:10,shadowColor:"#000",shadowOpacity:.08,shadowRadius:6,shadowOffset:{width:0,height:2}},instanceNavbarHeader:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",marginBottom:8,paddingLeft:2},instanceNavbarLabel:{fontSize:9,fontWeight:"700",color:s.color.textTertiary,textTransform:"uppercase",letterSpacing:1},instanceNavbarScroll:{gap:8,paddingRight:8},instanceNavbarButton:{flexDirection:"row",alignItems:"center",gap:6,paddingHorizontal:12,paddingVertical:8,backgroundColor:s.color.surfaceElevated,borderRadius:8,borderWidth:1,borderColor:s.color.border,minWidth:90},instanceNavbarButtonActive:{borderWidth:1.5,shadowColor:"#000",shadowOpacity:.1,shadowRadius:4,shadowOffset:{width:0,height:1}},instanceNavbarButtonText:{fontSize:11,fontWeight:"600",color:s.color.textSecondary,fontFamily:W,flex:1},instanceNavbarButtonTextActive:{fontWeight:"700",color:s.color.text},instanceNavbarBadge:{backgroundColor:s.color.bg,paddingHorizontal:6,paddingVertical:2,borderRadius:6,minWidth:24,alignItems:"center"},instanceNavbarBadgeText:{fontSize:10,fontWeight:"700",color:s.color.textSecondary,fontFamily:W},clearSearchButton:{marginTop:16,paddingHorizontal:16,paddingVertical:8,backgroundColor:s.color.surfaceElevated,borderRadius:6,borderWidth:1,borderColor:s.color.border},clearSearchText:{fontSize:13,color:s.color.text,fontWeight:"500"},limitBanner:{backgroundColor:s.color.surface,borderRadius:10,borderWidth:1,borderColor:s.color.accentBorderStrong,padding:12,marginTop:12},limitBannerContent:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",marginBottom:4},limitBannerLeft:{flexDirection:"row",alignItems:"center",gap:8},limitBannerText:{color:s.color.text,fontSize:13,fontWeight:"600"},limitBannerSubtext:{color:s.color.textTertiary,fontSize:11}});
4
+ registerMMKVInstance('mmkv.default', storage);`})]}),C==="mmkv"&&y.length>0&&d(f,{style:n.instanceNavbar,children:[d(f,{style:n.instanceNavbarHeader,children:[a(m,{style:n.instanceNavbarLabel,children:"INSTANCES"}),y.length>Ce&&a(ze,{style:{transform:[{scale:.85}]}})]}),d(Re,{horizontal:true,showsHorizontalScrollIndicator:false,contentContainerStyle:n.instanceNavbarScroll,children:[(M||y.length===1)&&d(ae,{onPress:()=>Te(null),testID:"buoy-storage-instance-all",accessibilityRole:"button",accessibilityLabel:`All ${wt.mmkv} instances`,style:[n.instanceNavbarButton,g===null&&n.instanceNavbarButtonActive],children:[a(Fe,{size:12,color:g===null?s.color.text:s.color.textSecondary}),a(m,{style:[n.instanceNavbarButtonText,g===null&&n.instanceNavbarButtonTextActive],children:"All"}),a(f,{style:n.instanceNavbarBadge,children:a(m,{style:n.instanceNavbarBadgeText,children:y.reduce((e,t)=>e+t.keyCount,0)})})]}),y.map((e,t)=>{const r=t>=Ce;return d(ae,{testID:`buoy-storage-instance-${e.id}`,accessibilityRole:"button",accessibilityLabel:`MMKV instance ${e.id}`,onPress:()=>{if(r){q(true)}else{Te(e.id)}},style:[n.instanceNavbarButton,e.id===g&&n.instanceNavbarButtonActive,{borderColor:r?s.color.border:L(e.id)+"40",backgroundColor:e.id===g?L(e.id)+"20":s.color.surfaceElevated,opacity:r?.5:1}],children:[a(Fe,{size:12,color:e.id===g?L(e.id):s.color.textSecondary}),a(m,{style:[n.instanceNavbarButtonText,e.id===g&&{color:L(e.id),fontWeight:"700"}],children:e.id}),a(f,{style:[n.instanceNavbarBadge,e.id===g&&{backgroundColor:L(e.id)+"30"}],children:a(m,{style:[n.instanceNavbarBadgeText,e.id===g&&{color:L(e.id)}],children:e.keyCount})})]},e.id)})]})]})]});const bt=a(Ft,{copyValue:ut,mmkvInstances:y.map(e=>({id:e.id,instance:e.instance})),activeStorageType:C,onClearComplete:k,isSelectMode:te,onToggleSelectMode:at,selectedCount:U.size});const Ct=te?a(Wt,{selectedKeys:yt,mmkvInstances:y.map(e=>({id:e.id,instance:e.instance})),onDeleteComplete:ct,onHideKeys:ne,onSelectAll:mt,onClearSelection:ft,totalVisibleKeys:B.length}):null;const vt=gt?d(ae,{style:n.limitBanner,onPress:()=>q(true),activeOpacity:.8,testID:"buoy-storage-locked-banner",accessibilityRole:"button",children:[d(f,{style:n.limitBannerContent,children:[d(f,{style:n.limitBannerLeft,children:[a(Mt,{size:16,color:s.color.accent}),a(m,{style:n.limitBannerText,children:w?`${Y} matching ${Y===1?"key":"keys"} in locked storage`:`${Y} keys locked`})]}),a(ze,{})]}),a(m,{style:n.limitBannerSubtext,children:w?"Upgrade to Pro to search your full storage":"Upgrade to Pro to unlock full storage access"})]}):null;const Tt=(()=>{const e=c.some(r=>!h(r.key));let t;if(w||!e){t=Bt({subject:"keys",verb:"registered",search:w,total:e?1:0,waiting:{otto:"empty",title:"No storage keys",message:"Nothing is registered for this tool to read."}});if(w&&e){t={...t,message:"No keys match. Clear the search to see them."}}}else if(T==="missing"){t={otto:"thumbsup",title:"No missing keys",message:"All required keys are present"}}else if(T==="issues"){t={otto:"cool",title:"No issues found",message:"All storage keys are correctly configured"}}else{t={otto:"broken",title:"No valid keys found",message:"All keys have issues or are missing"}}return a(xt,{...t,testID:"buoy-storage-keys-empty"})})();const kt=a(Kt,{visible:Q,onClose:()=>q(false),featureName:"Storage Keys"});return d(f,{style:n.root,children:[we>0?a(Dt,{onDone:()=>Ie(0)},we):null,d(Re,{keyboardShouldPersistTaps:"handled",testID:"buoy-storage-scroll",ref:Je,onScroll:e=>{Xe.current=e.nativeEvent.contentOffset.y},scrollEventThrottle:32,style:n.scrollContainer,contentContainerStyle:n.container,showsVerticalScrollIndicator:false,children:[a(f,{style:n.backgroundGrid}),a(Vt,{stats:D,tabStats:x,healthPercentage:F,healthStatus:ht,healthColor:pt,activeFilter:T,onFilterChange:Ue,activeStorageType:C,onStorageTypeChange:Ye,showStatus:!ee}),St,v.length>0?d(f,{style:n.keysSection,children:[d(f,{style:n.sectionHeader,children:[d(f,{style:n.sectionHeaderLeft,children:[d(m,{style:n.sectionTitle,children:[T==="all"?"KEYS":T==="missing"?"MISSING KEYS":"ISSUES TO FIX",C!=="all"&&` (${C.toUpperCase()})`]}),a(f,{style:n.countBadge,children:a(m,{style:n.countText,children:B.length})})]}),bt]}),Ct,a(Nt,{title:"",count:-1,keys:B,emptyMessage:"",isSelectMode:te,selectedKeys:U,onSelectionChange:lt,eventCountByKey:ge,onViewHistory:Z,onHideKey:e=>ne([e]),onToggleKey:dt,onDeleteKey:Ne,editBlockedFor:qe,pinnedKeys:_,onTogglePin:he,onRowRef:Ze,onOpenKey:He}),vt]}):Tt,a(m,{style:n.techFooter,children:"ASYNC STORAGE | MMKV | SECURE STORAGE BACKENDS"}),kt]})]})}const n=It.create({root:{flex:1,minHeight:0},editorOverlay:{...Ae,zIndex:10},scrollContainer:{flex:1,backgroundColor:"transparent"},container:{padding:12,paddingBottom:120},backgroundGrid:{...Ae,opacity:.006,backgroundColor:E.info},techFooter:{fontSize:8,color:s.color.textTertiary,fontFamily:W,textAlign:"center",marginTop:20,letterSpacing:1,opacity:.5},keysSection:{marginTop:8,backgroundColor:s.color.bg,borderRadius:12,padding:12,borderWidth:1,borderColor:s.color.border},sectionHeader:{flexDirection:"row",justifyContent:"space-between",alignItems:"center",marginBottom:10,paddingBottom:6,borderBottomWidth:1,borderBottomColor:s.color.separator},sectionHeaderLeft:{flexDirection:"row",alignItems:"center",gap:8},sectionTitle:{fontSize:12,fontWeight:"600",color:s.color.textSecondary,letterSpacing:.4,textTransform:"uppercase"},countBadge:{backgroundColor:s.color.surfaceElevated,paddingHorizontal:8,paddingVertical:3,borderRadius:6,borderWidth:1,borderColor:s.color.border},countText:{fontSize:11,fontWeight:"600",color:s.color.text,fontFamily:W},emptyState:{alignItems:"center",justifyContent:"center",paddingVertical:48},emptyTitle:{fontSize:16,fontWeight:"600",color:s.color.text,marginTop:12,marginBottom:8},emptySubtitle:{fontSize:13,color:s.color.textSecondary,textAlign:"center"},emptyMMKVState:{backgroundColor:s.color.surface,borderRadius:12,padding:20,borderWidth:1,borderColor:s.color.border,marginTop:8,alignItems:"center"},emptyMMKVTitle:{fontSize:14,fontWeight:"600",color:s.color.text,marginBottom:6},emptyMMKVSubtitle:{fontSize:12,color:s.color.textSecondary,textAlign:"center",marginBottom:12},emptyMMKVCode:{fontSize:10,fontFamily:W,color:s.color.accent,backgroundColor:s.color.bg,padding:12,borderRadius:8,borderWidth:1,borderColor:s.color.border,alignSelf:"stretch"},instanceNavbar:{marginTop:12,marginBottom:8,backgroundColor:s.color.surface,borderRadius:10,borderWidth:1,borderColor:s.color.border,padding:10,shadowColor:"#000",shadowOpacity:.08,shadowRadius:6,shadowOffset:{width:0,height:2}},instanceNavbarHeader:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",marginBottom:8,paddingLeft:2},instanceNavbarLabel:{fontSize:9,fontWeight:"700",color:s.color.textTertiary,textTransform:"uppercase",letterSpacing:1},instanceNavbarScroll:{gap:8,paddingRight:8},instanceNavbarButton:{flexDirection:"row",alignItems:"center",gap:6,paddingHorizontal:12,paddingVertical:8,backgroundColor:s.color.surfaceElevated,borderRadius:8,borderWidth:1,borderColor:s.color.border,minWidth:90},instanceNavbarButtonActive:{borderWidth:1.5,shadowColor:"#000",shadowOpacity:.1,shadowRadius:4,shadowOffset:{width:0,height:1}},instanceNavbarButtonText:{fontSize:11,fontWeight:"600",color:s.color.textSecondary,fontFamily:W,flex:1},instanceNavbarButtonTextActive:{fontWeight:"700",color:s.color.text},instanceNavbarBadge:{backgroundColor:s.color.bg,paddingHorizontal:6,paddingVertical:2,borderRadius:6,minWidth:24,alignItems:"center"},instanceNavbarBadgeText:{fontSize:10,fontWeight:"700",color:s.color.textSecondary,fontFamily:W},clearSearchButton:{marginTop:16,paddingHorizontal:16,paddingVertical:8,backgroundColor:s.color.surfaceElevated,borderRadius:6,borderWidth:1,borderColor:s.color.border},clearSearchText:{fontSize:13,color:s.color.text,fontWeight:"500"},limitBanner:{backgroundColor:s.color.surface,borderRadius:10,borderWidth:1,borderColor:s.color.accentBorderStrong,padding:12,marginTop:12},limitBannerContent:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",marginBottom:4},limitBannerLeft:{flexDirection:"row",alignItems:"center",gap:8},limitBannerText:{color:s.color.text,fontSize:13,fontWeight:"600"},limitBannerSubtext:{color:s.color.textTertiary,fontSize:11}});
@@ -1 +1 @@
1
- "use strict";import{storageLabels as x}from"../utils/storageLabels";import{useState as C}from"react";import{View as r,Text as n,StyleSheet as R,TouchableOpacity as c,ScrollView as T,Modal as I}from"react-native";import{macOSColors as d,night as o,monoFont as b}from"@buoy-gg/shared-ui";import{useMMKVInstances as v}from"../hooks/useMMKVInstances";import{isMMKVAvailable as B,getMMKVUnavailableMessage as M}from"../utils/mmkvAvailability";import{jsxs as i,jsx as t}from"react/jsx-runtime";export function MMKVInstanceSelector({selectedInstanceId:a,onSelectInstance:h,showRefreshButton:g=true}){const[w,s]=C(false);const{instances:p,instanceCount:f,refresh:y}=v(false);const u=p.find(l=>l.id===a);const S=l=>{h(l);s(false)};if(!B()){return t(r,{style:e.container,children:i(r,{style:e.unavailableState,children:[i(n,{style:e.unavailableTitle,children:[x.mmkv," Not Available"]}),t(n,{style:e.unavailableDescription,children:M()})]})})}if(f===0){return t(r,{style:e.container,children:i(r,{style:e.emptyState,children:[t(n,{style:e.emptyStateTitle,children:"No MMKV Instances Registered"}),t(n,{style:e.emptyStateDescription,children:"Register MMKV instances using registerMMKVInstance() to monitor them in dev tools."}),g&&t(c,{style:e.refreshButton,onPress:y,activeOpacity:.7,children:t(n,{style:e.refreshButtonText,children:"\u21BB Refresh"})})]})})}return i(r,{style:e.container,children:[i(c,{style:e.selectorButton,onPress:()=>s(true),activeOpacity:.7,children:[t(r,{style:e.selectorContent,children:u?t(m,{instance:u,isSelected:true}):t(n,{style:e.placeholderText,children:"Select MMKV Instance"})}),t(n,{style:e.dropdownArrow,children:"\u25BC"})]}),t(I,{visible:w,transparent:true,animationType:"fade",onRequestClose:()=>s(false),children:t(c,{style:e.modalOverlay,activeOpacity:1,onPress:()=>s(false),children:i(r,{style:e.dropdownContainer,children:[i(r,{style:e.dropdownHeader,children:[i(n,{style:e.dropdownTitle,children:["Select MMKV Instance (",f,")"]}),g&&t(c,{style:e.headerRefreshButton,onPress:y,activeOpacity:.7,children:t(n,{style:e.headerRefreshText,children:"\u21BB"})})]}),t(T,{style:e.dropdownList,children:p.map(l=>t(c,{style:[e.dropdownItem,l.id===a&&e.dropdownItemSelected],onPress:()=>S(l.id),activeOpacity:.7,children:t(m,{instance:l,isSelected:l.id===a})},l.id))})]})})})]})}function m({instance:a,isSelected:h}){return i(r,{style:e.instanceRow,children:[i(r,{style:e.instanceLeft,children:[t(n,{style:[e.instanceId,h&&e.instanceIdSelected],numberOfLines:1,children:a.id}),i(r,{style:e.instanceBadges,children:[a.encrypted&&t(r,{style:[e.badge,e.badgeEncrypted],children:t(n,{style:e.badgeText,children:"\u{1F512} Encrypted"})}),a.readOnly&&t(r,{style:[e.badge,e.badgeReadOnly],children:t(n,{style:e.badgeText,children:"\u{1F441}\uFE0F Read-only"})})]})]}),i(r,{style:e.instanceRight,children:[t(n,{style:e.keyCount,children:a.keyCount}),t(n,{style:e.keyCountLabel,children:"keys"})]})]})}const e=R.create({container:{marginBottom:12},unavailableState:{backgroundColor:d.semantic.warning+"15",borderRadius:12,padding:20,borderWidth:1,borderColor:d.semantic.warning+"40",alignItems:"center",gap:12},unavailableTitle:{fontSize:14,fontWeight:"600",color:d.semantic.warning},unavailableDescription:{fontSize:12,color:o.color.textSecondary,textAlign:"center",lineHeight:18},emptyState:{backgroundColor:o.color.surface,borderRadius:12,padding:20,borderWidth:1,borderColor:o.color.border,alignItems:"center",gap:12},emptyStateTitle:{fontSize:14,fontWeight:"600",color:o.color.text},emptyStateDescription:{fontSize:12,color:o.color.textTertiary,textAlign:"center",lineHeight:18},refreshButton:{marginTop:8,paddingHorizontal:16,paddingVertical:8,backgroundColor:o.color.accentSoft,borderRadius:8,borderWidth:1,borderColor:o.color.accentBorderStrong},refreshButtonText:{fontSize:12,fontWeight:"600",color:o.color.accent},selectorButton:{backgroundColor:o.color.surface,borderRadius:12,borderWidth:1,borderColor:o.color.border,padding:12,flexDirection:"row",alignItems:"center",justifyContent:"space-between",shadowColor:"#000000",shadowOpacity:.03,shadowRadius:8,shadowOffset:{width:0,height:2}},selectorContent:{flex:1},placeholderText:{fontSize:13,color:o.color.placeholder,fontStyle:"italic"},dropdownArrow:{fontSize:10,color:o.color.textTertiary,marginLeft:8},modalOverlay:{flex:1,backgroundColor:"rgba(0, 0, 0, 0.5)",justifyContent:"center",alignItems:"center",padding:20},dropdownContainer:{backgroundColor:o.color.surface,borderRadius:16,borderWidth:1,borderColor:o.color.border,width:"100%",maxWidth:500,maxHeight:"70%",shadowColor:"#000000",shadowOpacity:.2,shadowRadius:20,shadowOffset:{width:0,height:10},overflow:"hidden"},dropdownHeader:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",padding:16,borderBottomWidth:1,borderBottomColor:o.color.separator},dropdownTitle:{fontSize:14,fontWeight:"600",color:o.color.text},headerRefreshButton:{padding:4},headerRefreshText:{fontSize:18,color:o.color.accent},dropdownList:{maxHeight:400},dropdownItem:{padding:12,borderBottomWidth:1,borderBottomColor:o.color.separator},dropdownItemSelected:{backgroundColor:o.color.accentSoft},instanceRow:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",gap:12},instanceLeft:{flex:1,gap:6},instanceId:{fontSize:13,fontWeight:"500",color:o.color.text,fontFamily:b},instanceIdSelected:{fontWeight:"600",color:o.color.accent},instanceBadges:{flexDirection:"row",flexWrap:"wrap",gap:6},badge:{paddingHorizontal:6,paddingVertical:2,borderRadius:4,borderWidth:1},badgeEncrypted:{backgroundColor:d.semantic.success+"15",borderColor:d.semantic.success+"40"},badgeReadOnly:{backgroundColor:d.semantic.warning+"15",borderColor:d.semantic.warning+"40"},badgeText:{fontSize:9,fontWeight:"500",color:o.color.textSecondary},instanceRight:{alignItems:"flex-end"},keyCount:{fontSize:16,fontWeight:"600",color:o.color.text,fontFamily:b},keyCountLabel:{fontSize:9,color:o.color.textTertiary,textTransform:"uppercase",letterSpacing:.5}});
1
+ "use strict";import{storageLabels as x}from"../utils/storageLabels";import{useState as C}from"react";import{View as r,Text as n,StyleSheet as T,TouchableOpacity as c,ScrollView as R,Modal as I}from"react-native";import{macOSColors as d,night as o,monoFont as b}from"@buoy-gg/shared-ui";import{useMMKVInstances as v}from"../hooks/useMMKVInstances";import{isMMKVAvailable as B,getMMKVUnavailableMessage as M}from"../utils/mmkvAvailability";import{jsxs as i,jsx as t}from"react/jsx-runtime";export function MMKVInstanceSelector({selectedInstanceId:a,onSelectInstance:h,showRefreshButton:p=true}){const[w,s]=C(false);const{instances:g,instanceCount:y,refresh:f}=v(false);const u=g.find(l=>l.id===a);const S=l=>{h(l);s(false)};if(!B()){return t(r,{style:e.container,children:i(r,{style:e.unavailableState,children:[i(n,{style:e.unavailableTitle,children:[x.mmkv," Not Available"]}),t(n,{style:e.unavailableDescription,children:M()})]})})}if(y===0){return t(r,{style:e.container,children:i(r,{style:e.emptyState,children:[t(n,{style:e.emptyStateTitle,children:"No MMKV Instances Registered"}),t(n,{style:e.emptyStateDescription,children:"Register MMKV instances using registerMMKVInstance() to monitor them in dev tools."}),p&&t(c,{style:e.refreshButton,onPress:f,activeOpacity:.7,children:t(n,{style:e.refreshButtonText,children:"\u21BB Refresh"})})]})})}return i(r,{style:e.container,children:[i(c,{style:e.selectorButton,onPress:()=>s(true),activeOpacity:.7,children:[t(r,{style:e.selectorContent,children:u?t(m,{instance:u,isSelected:true}):t(n,{style:e.placeholderText,children:"Select MMKV Instance"})}),t(n,{style:e.dropdownArrow,children:"\u25BC"})]}),t(I,{visible:w,transparent:true,animationType:"fade",onRequestClose:()=>s(false),children:t(c,{style:e.modalOverlay,activeOpacity:1,onPress:()=>s(false),children:i(r,{style:e.dropdownContainer,children:[i(r,{style:e.dropdownHeader,children:[i(n,{style:e.dropdownTitle,children:["Select MMKV Instance (",y,")"]}),p&&t(c,{style:e.headerRefreshButton,onPress:f,activeOpacity:.7,children:t(n,{style:e.headerRefreshText,children:"\u21BB"})})]}),t(R,{keyboardShouldPersistTaps:"handled",style:e.dropdownList,children:g.map(l=>t(c,{style:[e.dropdownItem,l.id===a&&e.dropdownItemSelected],onPress:()=>S(l.id),activeOpacity:.7,children:t(m,{instance:l,isSelected:l.id===a})},l.id))})]})})})]})}function m({instance:a,isSelected:h}){return i(r,{style:e.instanceRow,children:[i(r,{style:e.instanceLeft,children:[t(n,{style:[e.instanceId,h&&e.instanceIdSelected],numberOfLines:1,children:a.id}),i(r,{style:e.instanceBadges,children:[a.encrypted&&t(r,{style:[e.badge,e.badgeEncrypted],children:t(n,{style:e.badgeText,children:"\u{1F512} Encrypted"})}),a.readOnly&&t(r,{style:[e.badge,e.badgeReadOnly],children:t(n,{style:e.badgeText,children:"\u{1F441}\uFE0F Read-only"})})]})]}),i(r,{style:e.instanceRight,children:[t(n,{style:e.keyCount,children:a.keyCount}),t(n,{style:e.keyCountLabel,children:"keys"})]})]})}const e=T.create({container:{marginBottom:12},unavailableState:{backgroundColor:d.semantic.warning+"15",borderRadius:12,padding:20,borderWidth:1,borderColor:d.semantic.warning+"40",alignItems:"center",gap:12},unavailableTitle:{fontSize:14,fontWeight:"600",color:d.semantic.warning},unavailableDescription:{fontSize:12,color:o.color.textSecondary,textAlign:"center",lineHeight:18},emptyState:{backgroundColor:o.color.surface,borderRadius:12,padding:20,borderWidth:1,borderColor:o.color.border,alignItems:"center",gap:12},emptyStateTitle:{fontSize:14,fontWeight:"600",color:o.color.text},emptyStateDescription:{fontSize:12,color:o.color.textTertiary,textAlign:"center",lineHeight:18},refreshButton:{marginTop:8,paddingHorizontal:16,paddingVertical:8,backgroundColor:o.color.accentSoft,borderRadius:8,borderWidth:1,borderColor:o.color.accentBorderStrong},refreshButtonText:{fontSize:12,fontWeight:"600",color:o.color.accent},selectorButton:{backgroundColor:o.color.surface,borderRadius:12,borderWidth:1,borderColor:o.color.border,padding:12,flexDirection:"row",alignItems:"center",justifyContent:"space-between",shadowColor:"#000000",shadowOpacity:.03,shadowRadius:8,shadowOffset:{width:0,height:2}},selectorContent:{flex:1},placeholderText:{fontSize:13,color:o.color.placeholder,fontStyle:"italic"},dropdownArrow:{fontSize:10,color:o.color.textTertiary,marginLeft:8},modalOverlay:{flex:1,backgroundColor:"rgba(0, 0, 0, 0.5)",justifyContent:"center",alignItems:"center",padding:20},dropdownContainer:{backgroundColor:o.color.surface,borderRadius:16,borderWidth:1,borderColor:o.color.border,width:"100%",maxWidth:500,maxHeight:"70%",shadowColor:"#000000",shadowOpacity:.2,shadowRadius:20,shadowOffset:{width:0,height:10},overflow:"hidden"},dropdownHeader:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",padding:16,borderBottomWidth:1,borderBottomColor:o.color.separator},dropdownTitle:{fontSize:14,fontWeight:"600",color:o.color.text},headerRefreshButton:{padding:4},headerRefreshText:{fontSize:18,color:o.color.accent},dropdownList:{maxHeight:400},dropdownItem:{padding:12,borderBottomWidth:1,borderBottomColor:o.color.separator},dropdownItemSelected:{backgroundColor:o.color.accentSoft},instanceRow:{flexDirection:"row",alignItems:"center",justifyContent:"space-between",gap:12},instanceLeft:{flex:1,gap:6},instanceId:{fontSize:13,fontWeight:"500",color:o.color.text,fontFamily:b},instanceIdSelected:{fontWeight:"600",color:o.color.accent},instanceBadges:{flexDirection:"row",flexWrap:"wrap",gap:6},badge:{paddingHorizontal:6,paddingVertical:2,borderRadius:4,borderWidth:1},badgeEncrypted:{backgroundColor:d.semantic.success+"15",borderColor:d.semantic.success+"40"},badgeReadOnly:{backgroundColor:d.semantic.warning+"15",borderColor:d.semantic.warning+"40"},badgeText:{fontSize:9,fontWeight:"500",color:o.color.textSecondary},instanceRight:{alignItems:"flex-end"},keyCount:{fontSize:16,fontWeight:"600",color:o.color.text,fontFamily:b},keyCountLabel:{fontSize:9,color:o.color.textTertiary,textTransform:"uppercase",letterSpacing:.5}});
@@ -1 +1 @@
1
- "use strict";import{useState as g,useCallback as i,useEffect as ee,useRef as be,useMemo as y}from"react";import{View as S,TouchableOpacity as te,StyleSheet as lt,FlatList as Ee,Alert as ne}from"react-native";import oe from"../utils/appAsyncStorage";import{JsModal as it,ModalHeader as c,TabSelector as ct,parseValue as dt,devToolsStorageKeys as P,macOSColors as ut,night as d,ToolEmptyState as gt,Filter as yt,RefreshCw as pt,Search as mt,SearchBar as ft,PowerToggleButton as ht,ToolbarCopyButton as Ce,ToolbarClearButton as St,truncatePayload as _,TickProvider as Ie,useLimit as vt,TIER_LIMITS as Tt,windowDragProps as bt,usePersistedState as M,monoFont as L}from"@buoy-gg/shared-ui";import{StorageBrowserMode as Et}from"./StorageBrowserMode";import{StorageTypeFilterBar as Ct,countByStorageType as It}from"./StorageTypeFilterBar";import{clearAllAppStorage as xt,clearAllStorageIncludingDevTools as kt}from"../utils/clearAllStorage";import{ProFeatureBanner as wt}from"@buoy-gg/shared-ui";import{useStorageEvents as Bt}from"../hooks/useStorageEvents";import{StorageEventDetailContent as xe,StorageEventDetailFooter as ke}from"./StorageEventDetailContent";import{StorageEventFilterView as Ft}from"./StorageEventFilterView";import{StorageEventCard as we}from"./StorageEventCard";import{useIsPro as Pt}from"@buoy-gg/license";import{jsx as n,jsxs as p,Fragment as Be}from"react/jsx-runtime";export const FREE_TIER_EVENT_LIMIT=Tt["storage.events"].free;const re={getItem:r=>oe.getItem(r),setItem:(r,C)=>oe.setItem(r,C)};const At={storage:re,parse:r=>r==="browser"||r==="events"?r:void 0,serialize:r=>r};const Dt={storage:re,parse:r=>r==="true",serialize:r=>r.toString()};const Fe={storage:re,parse:r=>new Set(JSON.parse(r)),serialize:r=>JSON.stringify(Array.from(r))};const Rt={...Fe,parse:r=>{const C=JSON.parse(r);if(!C.includes("@react_buoy"))C.push("@react_buoy");return new Set(C)}};export function StorageModalWithTabs({visible:r,onClose:C,onBack:V,onMinimize:Pe,enableSharedModalDimensions:Ae=false,requiredStorageKeys:De=[],inline:Re=false,onTabChange:ae,onRefresh:se,onEventSelect:K}){const Kt=Pt();const N=vt("storage.events");const[B,Ke]=M(P.storage.activeTab(),"browser",At);ee(()=>{ae?.(B)},[B,ae]);const[le,ie]=g("");const[W,H]=g(null);const[j,$]=g(false);const[ce,Ne]=M(P.storage.isMonitoring(),true,Dt);const{events:F,clearEvents:de,isCapturing:He}=Bt({enabled:ce});const[G,A]=g(null);const[I,J]=g(null);const[h,v]=g(null);const[z,x]=g(0);const[D,Q]=g(false);const[T,ue]=M(P.storage.eventFilters(),new Set(["@react_buoy","@RNAsyncStorage","redux-persist","persist:"]),Rt);const[k,ge]=g("all");const[b,ze]=g(new Set(["async","mmkv","secure"]));const[Oe,_e]=M(P.storage.pinnedKeys(),new Set,Fe);const Nt=be(null);const ye=ce&&He;const[q,Me]=g("bottomSheet");const Le=i(e=>{Me(e)},[]);const Ve=i(()=>{Ne(e=>!e)},[]);const We=i(()=>{de();A(null);x(0)},[de]);const je=i(e=>{J(e);v(null)},[]);const pe=i(()=>{J(null);v(null)},[]);const me=i(e=>{ue(t=>{const o=new Set(t);if(o.has(e)){o.delete(e)}else{o.add(e)}return o})},[]);const fe=i(e=>{ue(t=>new Set([...t,e]))},[]);const $e=i(e=>{_e(t=>{const o=new Set(t);if(o.has(e)){o.delete(e)}else{o.add(e)}return o})},[]);const Ge=i(()=>{Q(!D)},[D]);const Je=i(e=>{ze(t=>{const o=new Set(t);if(o.has(e)){o.delete(e)}else{o.add(e)}return o})},[]);const U=be([]);const Qe=i(()=>{const e=U.current;return{timestamp:new Date().toISOString(),totalKeys:e.length,asyncStorage:e.filter(t=>t.storageType==="async").reduce((t,o)=>{t[o.key]=_(o.value);return t},{}),mmkv:e.filter(t=>t.storageType==="mmkv").reduce((t,o)=>{const a=o.instanceId||"default";if(!t[a])t[a]={};t[a][o.key]=_(o.value);return t},{}),secure:e.filter(t=>t.storageType==="secure").reduce((t,o)=>{t[o.key]=_(o.value);return t},{})}},[]);const Ht=i(async()=>{ne.alert("Clear Storage","Choose what to clear:",[{text:"Cancel",style:"cancel"},{text:"Clear App Storage",onPress:async()=>{try{await xt()}catch(e){ne.alert("Error","Failed to clear app storage")}}},{text:"Clear All (Including Dev Tools)",style:"destructive",onPress:async()=>{try{await kt()}catch(e){ne.alert("Error","Failed to clear all storage")}}}])},[]);const O=e=>{const t=dt(e);if(t===null)return"null";if(t===void 0)return"undefined";if(Array.isArray(t))return"array";if(typeof t==="boolean")return"boolean";if(typeof t==="number")return"number";if(typeof t==="string")return"string";if(typeof t==="object")return"object";return"undefined"};const[he,qe]=g([]);ee(()=>{const e=async()=>{try{const t=await oe.getAllKeys();qe([...t].sort())}catch(t){}};if(r){e()}},[r]);const Ue=y(()=>{const e=new Set(he);F.forEach(t=>{if(t.data?.key){e.add(t.data.key)}});return Array.from(e).sort()},[F,he]);const m=y(()=>{const e=new Map;F.forEach(t=>{if(!t.data?.key)return;const o=t.data.key;if(!b.has(t.storageType))return;const a=Array.from(T).some(w=>o.includes(w));if(a)return;const s=e.get(o);if(!s){e.set(o,{key:o,lastEvent:t,events:[t],totalOperations:1,currentValue:t.data.value,valueType:O(t.data.value),storageTypes:new Set([t.storageType])})}else{s.events.push(t);s.totalOperations++;s.storageTypes.add(t.storageType);if(t.timestamp>s.lastEvent.timestamp){s.lastEvent=t;s.currentValue=t.data.value;s.valueType=O(t.data.value)}}});return Array.from(e.values()).sort((t,o)=>o.lastEvent.timestamp.getTime()-t.lastEvent.timestamp.getTime())},[F,T,b]);const u=y(()=>{if(!G)return null;return m.find(e=>e.key===G)||null},[G,m]);const Ye=y(()=>{const e={};m.forEach(t=>{e[t.key]=t.totalOperations});return e},[m]);const Xe=y(()=>{const e={};m.forEach(t=>{e[t.key]=t.lastEvent.timestamp.getTime()});return e},[m]);const E=y(()=>{if(!I)return null;return m.find(e=>e.key===I)||null},[I,m]);ee(()=>{if(!K)return;const e=u?u:h!==null?E:null;const t=u?z:h;if(!e||t==null)return;const o=[...e.events].sort((w,Z)=>w.timestamp.getTime()-Z.timestamp.getTime());const a=o[t];const s=o[t-1];if(a)K(a);if(s)K(s)},[K,u,z,E,h]);const R=y(()=>{return F.filter(e=>{if(!e.data?.key)return false;if(!b.has(e.storageType))return false;const t=e.data.key;return!Array.from(T).some(o=>t.includes(o))})},[F,T,b]);const Ze=y(()=>It(R),[R]);const f=y(()=>{if(k==="all")return R;return R.filter(e=>e.storageType===k)},[R,k]);const et=i(()=>{return f.map(e=>({key:e.data?.key,action:e.action,value:_(e.data?.value),storageType:e.storageType,timestamp:e.timestamp.toISOString()}))},[f]);const tt=y(()=>f.slice(0,N),[f,N]);const Y=y(()=>Math.max(0,f.length-N),[f.length,N]);const nt=.8;const ot=i(e=>e.id,[]);const Se=i(e=>{const t=m.find(s=>s.key===e.data?.key);if(!t)return;const o=[...t.events].sort((s,w)=>s.timestamp.getTime()-w.timestamp.getTime());const a=o.findIndex(s=>s.timestamp.getTime()===e.timestamp.getTime());A(t.key);x(a>=0?a:0)},[m]);const rt=i(({item:e})=>{const t={key:e.data?.key||"",lastAction:e.action,totalOperations:1,lastEventTimestamp:e.timestamp,storageTypes:new Set([e.storageType]),valueType:O(e.data?.value)};return n(we,{data:t,onPress:()=>Se(e),testID:`buoy-storage-event-${e.id}`})},[Se]);if(!r)return null;const at=Ae?P.modal.root():P.storage.modal();const ve=()=>{if(D){return n(Ft,{ignoredPatterns:T,onTogglePattern:me,onAddPattern:fe,availableKeys:Ue,enabledStorageTypes:b,onToggleStorageType:Je})}if(B==="browser"){if(I&&E){if(h!==null){return n(S,{style:l.contentWrapper,children:n(xe,{conversation:E,selectedEventIndex:h,onEventIndexChange:v,disableInternalFooter:true})})}const t=[...E.events].sort((a,s)=>a.timestamp.getTime()-s.timestamp.getTime());const o=[...t].reverse();return n(Ee,{testID:"buoy-storage-history-list",style:l.flexFill,data:o,keyExtractor:a=>a.id,renderItem:({item:a})=>{const s=t.findIndex(Z=>Z.timestamp.getTime()===a.timestamp.getTime());const w={key:a.data?.key||"",lastAction:a.action,totalOperations:1,lastEventTimestamp:a.timestamp,storageTypes:new Set([a.storageType]),valueType:O(a.data?.value)};return n(we,{data:w,onPress:()=>v(s>=0?s:0),testID:`buoy-storage-history-event-${a.id}`})},contentContainerStyle:l.listContent,ItemSeparatorComponent:()=>n(S,{style:l.separator}),initialNumToRender:20})}return n(Et,{requiredStorageKeys:De,ignoredPatterns:T,onTogglePattern:me,onAddPattern:fe,searchQuery:le,storageDataRef:U,eventCountByKey:Ye,lastWriteByKey:Xe,onViewHistory:je,enabledStorageTypes:b,pinnedKeys:Oe,onTogglePin:$e,applySafeAreaInset:q==="bottomSheet",storageTypeFilter:k,onStorageTypeFilterChange:ge,detailKey:W,onOpenKey:H,onCloseDetail:()=>H(null)})}if(u){return n(S,{style:l.contentWrapper,children:n(xe,{conversation:u,selectedEventIndex:z,onEventIndexChange:x,disableInternalFooter:true})})}const e=n(S,{style:l.eventFilterBar,children:n(Ct,{active:k,onChange:ge,counts:Ze})});if(f.length===0){const t=k!=="all";return p(S,{style:l.flexFill,children:[e,n(gt,{testID:"buoy-storage-events-empty",...!ye?{otto:"paused",title:"Event listener is paused",message:"Press play to start monitoring"}:t?{otto:"filtering",title:`No ${k} events`,message:"Other backends have events \u2014 pick All Types to see them"}:{otto:"listening",title:"No storage events yet",message:"Storage operations will appear here"}})]})}return p(S,{style:l.flexFill,children:[e,n(Ee,{testID:"buoy-storage-events-list",style:l.flexFill,data:tt,renderItem:rt,keyExtractor:ot,onEndReachedThreshold:nt,contentContainerStyle:l.listContent,ListFooterComponent:Y>0?n(S,{style:l.lockedBannerContainer,children:n(wt,{featureName:`${Y} event${Y>1?"s":""} locked`,description:"Upgrade to Pro to unlock full event history"})}):null,initialNumToRender:10,maxToRenderPerBatch:10,windowSize:10})]})};const X=u&&u.events.length>1?n(ke,{conversation:u,selectedEventIndex:z,onEventIndexChange:x,applySafeAreaInset:q==="bottomSheet"}):E&&h!==null&&E.events.length>1?n(ke,{conversation:E,selectedEventIndex:h,onEventIndexChange:v,applySafeAreaInset:q==="bottomSheet"}):null;const st=D?()=>Q(false):h!==null?()=>v(null):I?pe:u?()=>{A(null);x(0)}:V;const Te=D?p(c,{children:[n(c.Navigation,{onBack:()=>Q(false)}),n(c.Content,{title:"Filters"})]}):I?p(c,{children:[n(c.Navigation,{onBack:h!==null?()=>v(null):pe}),n(c.Content,{title:`${I} History`,centered:true})]}):u?p(c,{children:[n(c.Navigation,{onBack:()=>{A(null);x(0)}}),n(c.Content,{title:u.key})]}):W?p(c,{children:[n(c.Navigation,{onBack:()=>H(null)}),n(c.Content,{title:W.key,centered:true,testID:"buoy-storage-detail-title"})]}):p(c,{children:[V&&n(c.Navigation,{onBack:V}),n(c.Content,{title:"",children:j?n(ft,{value:le,onChange:ie,onClear:()=>{ie("");$(false)},placeholder:"Search storage keys...",testID:"buoy-storage-search",autoFocus:true,onSubmitEditing:()=>$(false),returnKeyType:"search",containerStyle:l.headerSearchContainer}):n(ct,{tabs:[{key:"browser",label:"Storage"},{key:"events",label:`Events${f.length>0?` (${f.length})`:""}`}],activeTab:B,testIDPrefix:"buoy-storage-tab",onTabChange:e=>{Ke(e);J(null);v(null);A(null);x(0);H(null)}})}),p(c.Actions,{children:[se&&!j?n(te,{onPress:se,style:l.iconButton,testID:"buoy-storage-refresh",accessibilityLabel:"Refresh storage",accessibilityRole:"button",children:n(pt,{size:14,color:d.color.textSecondary})}):null,n(te,{onPress:Ge,testID:"buoy-storage-filters",accessibilityLabel:"Storage filters",accessibilityRole:"button",style:[l.iconButton,(T.size>0||b.size<3)&&l.activeFilterButton],children:n(yt,{size:14,color:T.size>0||b.size<3?d.color.accent:d.color.textSecondary})}),B==="browser"&&!j&&p(Be,{children:[n(te,{onPress:()=>$(true),testID:"buoy-storage-search-open",accessibilityLabel:"Open search",accessibilityRole:"button",style:l.iconButton,children:n(mt,{size:14,color:d.color.textSecondary})}),n(Ce,{value:Qe,disabled:U.current.length===0,buttonStyle:l.iconButton,testID:"buoy-storage-copy"})]}),B==="events"&&p(Be,{children:[n(Ce,{value:et,disabled:f.length===0,buttonStyle:l.iconButton,testID:"buoy-storage-events-copy"}),n(ht,{isEnabled:ye,onToggle:Ve,accessibilityLabel:"Toggle storage event monitoring",testID:"buoy-storage-power"}),n(St,{onPress:We,buttonStyle:l.iconButton,testID:"buoy-storage-clear-events"})]})]})]});if(Re){return n(Ie,{children:p(S,{style:l.inlineRoot,children:[n(S,{style:l.inlineHeader,...bt,children:Te}),ve(),X]})})}return n(Ie,{children:n(it,{visible:r,onClose:C,onBack:st,onMinimize:Pe,persistenceKey:at,header:{showToggleButton:true,customContent:Te},onModeChange:Le,enablePersistence:true,initialMode:"bottomSheet",enableGlitchEffects:true,styles:{},footer:X,footerHeight:X?68:0,disableScrollWrapper:true,children:ve()})})}export function StorageToolView(r={}){return n(StorageModalWithTabs,{...r,inline:true,visible:true,onClose:()=>{}})}const l=lt.create({inlineRoot:{flex:1,minHeight:0,backgroundColor:"transparent"},inlineHeader:{paddingHorizontal:12,paddingVertical:8,borderBottomWidth:1,borderBottomColor:ut.border.default,backgroundColor:"transparent"},headerSearchContainer:{flex:1},flexFill:{flex:1},iconButton:{width:32,height:32,borderRadius:8,backgroundColor:d.color.buttonSurface,borderWidth:1,borderColor:d.color.border,alignItems:"center",justifyContent:"center"},activeFilterButton:{backgroundColor:d.color.accentSoft,borderColor:d.color.accentBorderStrong},separator:{height:8},listContent:{paddingVertical:6},lockedBannerContainer:{marginTop:8,marginHorizontal:16},eventFilterBar:{paddingHorizontal:12,paddingTop:8,paddingBottom:4},emptyState:{flex:1,justifyContent:"center",alignItems:"center",padding:32},emptyTitle:{color:d.color.text,fontSize:16,fontWeight:"600",marginTop:16,marginBottom:8,fontFamily:L,letterSpacing:.5,textTransform:"uppercase"},emptySubtitle:{color:d.color.textSecondary,fontSize:14,textAlign:"center",fontFamily:L},eventNavigation:{flexDirection:"row",alignItems:"center",gap:8,paddingHorizontal:8},navButton:{padding:4,borderRadius:4},navButtonDisabled:{opacity:.3},eventCounter:{color:d.color.text,fontSize:12,fontWeight:"600",fontFamily:L,paddingHorizontal:8},headerTopRow:{flexDirection:"row",alignItems:"center",gap:8,marginBottom:12},keyNameContainer:{flex:1,flexDirection:"row",alignItems:"center",gap:6,backgroundColor:d.color.surfaceElevated,paddingHorizontal:10,paddingVertical:4,borderRadius:6,borderWidth:1,borderColor:d.color.border,height:28},keyNameText:{flex:1,fontSize:13,fontWeight:"600",color:d.color.accent,fontFamily:L,letterSpacing:.5},contentWrapper:{flex:1}});
1
+ "use strict";import{useState as g,useCallback as i,useEffect as ee,useRef as be,useMemo as y}from"react";import{View as S,TouchableOpacity as te,StyleSheet as lt,FlatList as Ee,Alert as ne}from"react-native";import oe from"../utils/appAsyncStorage";import{JsModal as it,ModalHeader as c,TabSelector as ct,parseValue as dt,devToolsStorageKeys as P,macOSColors as ut,night as d,ToolEmptyState as gt,Filter as yt,RefreshCw as pt,Search as mt,SearchBar as ft,PowerToggleButton as ht,ToolbarCopyButton as Ce,ToolbarClearButton as St,truncatePayload as _,TickProvider as Ie,useLimit as vt,TIER_LIMITS as Tt,windowDragProps as bt,usePersistedState as M,monoFont as L}from"@buoy-gg/shared-ui";import{StorageBrowserMode as Et}from"./StorageBrowserMode";import{StorageTypeFilterBar as Ct,countByStorageType as It}from"./StorageTypeFilterBar";import{clearAllAppStorage as xt,clearAllStorageIncludingDevTools as kt}from"../utils/clearAllStorage";import{ProFeatureBanner as wt}from"@buoy-gg/shared-ui";import{useStorageEvents as Bt}from"../hooks/useStorageEvents";import{StorageEventDetailContent as xe,StorageEventDetailFooter as ke}from"./StorageEventDetailContent";import{StorageEventFilterView as Ft}from"./StorageEventFilterView";import{StorageEventCard as we}from"./StorageEventCard";import{useIsPro as Pt}from"@buoy-gg/license";import{jsx as n,jsxs as p,Fragment as Be}from"react/jsx-runtime";export const FREE_TIER_EVENT_LIMIT=Tt["storage.events"].free;const re={getItem:r=>oe.getItem(r),setItem:(r,C)=>oe.setItem(r,C)};const At={storage:re,parse:r=>r==="browser"||r==="events"?r:void 0,serialize:r=>r};const Dt={storage:re,parse:r=>r==="true",serialize:r=>r.toString()};const Fe={storage:re,parse:r=>new Set(JSON.parse(r)),serialize:r=>JSON.stringify(Array.from(r))};const Rt={...Fe,parse:r=>{const C=JSON.parse(r);if(!C.includes("@react_buoy"))C.push("@react_buoy");return new Set(C)}};export function StorageModalWithTabs({visible:r,onClose:C,onBack:V,onMinimize:Pe,enableSharedModalDimensions:Ae=false,requiredStorageKeys:De=[],inline:Re=false,onTabChange:ae,onRefresh:se,onEventSelect:K}){const Kt=Pt();const N=vt("storage.events");const[B,Ke]=M(P.storage.activeTab(),"browser",At);ee(()=>{ae?.(B)},[B,ae]);const[le,ie]=g("");const[W,H]=g(null);const[j,$]=g(false);const[ce,Ne]=M(P.storage.isMonitoring(),true,Dt);const{events:F,clearEvents:de,isCapturing:He}=Bt({enabled:ce});const[G,A]=g(null);const[I,J]=g(null);const[h,v]=g(null);const[z,x]=g(0);const[D,Q]=g(false);const[T,ue]=M(P.storage.eventFilters(),new Set(["@react_buoy","@RNAsyncStorage","redux-persist","persist:"]),Rt);const[k,ge]=g("all");const[b,ze]=g(new Set(["async","mmkv","secure"]));const[Oe,_e]=M(P.storage.pinnedKeys(),new Set,Fe);const Nt=be(null);const ye=ce&&He;const[q,Me]=g("bottomSheet");const Le=i(e=>{Me(e)},[]);const Ve=i(()=>{Ne(e=>!e)},[]);const We=i(()=>{de();A(null);x(0)},[de]);const je=i(e=>{J(e);v(null)},[]);const pe=i(()=>{J(null);v(null)},[]);const me=i(e=>{ue(t=>{const o=new Set(t);if(o.has(e)){o.delete(e)}else{o.add(e)}return o})},[]);const fe=i(e=>{ue(t=>new Set([...t,e]))},[]);const $e=i(e=>{_e(t=>{const o=new Set(t);if(o.has(e)){o.delete(e)}else{o.add(e)}return o})},[]);const Ge=i(()=>{Q(!D)},[D]);const Je=i(e=>{ze(t=>{const o=new Set(t);if(o.has(e)){o.delete(e)}else{o.add(e)}return o})},[]);const U=be([]);const Qe=i(()=>{const e=U.current;return{timestamp:new Date().toISOString(),totalKeys:e.length,asyncStorage:e.filter(t=>t.storageType==="async").reduce((t,o)=>{t[o.key]=_(o.value);return t},{}),mmkv:e.filter(t=>t.storageType==="mmkv").reduce((t,o)=>{const a=o.instanceId||"default";if(!t[a])t[a]={};t[a][o.key]=_(o.value);return t},{}),secure:e.filter(t=>t.storageType==="secure").reduce((t,o)=>{t[o.key]=_(o.value);return t},{})}},[]);const Ht=i(async()=>{ne.alert("Clear Storage","Choose what to clear:",[{text:"Cancel",style:"cancel"},{text:"Clear App Storage",onPress:async()=>{try{await xt()}catch(e){ne.alert("Error","Failed to clear app storage")}}},{text:"Clear All (Including Dev Tools)",style:"destructive",onPress:async()=>{try{await kt()}catch(e){ne.alert("Error","Failed to clear all storage")}}}])},[]);const O=e=>{const t=dt(e);if(t===null)return"null";if(t===void 0)return"undefined";if(Array.isArray(t))return"array";if(typeof t==="boolean")return"boolean";if(typeof t==="number")return"number";if(typeof t==="string")return"string";if(typeof t==="object")return"object";return"undefined"};const[he,qe]=g([]);ee(()=>{const e=async()=>{try{const t=await oe.getAllKeys();qe([...t].sort())}catch(t){}};if(r){e()}},[r]);const Ue=y(()=>{const e=new Set(he);F.forEach(t=>{if(t.data?.key){e.add(t.data.key)}});return Array.from(e).sort()},[F,he]);const m=y(()=>{const e=new Map;F.forEach(t=>{if(!t.data?.key)return;const o=t.data.key;if(!b.has(t.storageType))return;const a=Array.from(T).some(w=>o.includes(w));if(a)return;const s=e.get(o);if(!s){e.set(o,{key:o,lastEvent:t,events:[t],totalOperations:1,currentValue:t.data.value,valueType:O(t.data.value),storageTypes:new Set([t.storageType])})}else{s.events.push(t);s.totalOperations++;s.storageTypes.add(t.storageType);if(t.timestamp>s.lastEvent.timestamp){s.lastEvent=t;s.currentValue=t.data.value;s.valueType=O(t.data.value)}}});return Array.from(e.values()).sort((t,o)=>o.lastEvent.timestamp.getTime()-t.lastEvent.timestamp.getTime())},[F,T,b]);const u=y(()=>{if(!G)return null;return m.find(e=>e.key===G)||null},[G,m]);const Ye=y(()=>{const e={};m.forEach(t=>{e[t.key]=t.totalOperations});return e},[m]);const Xe=y(()=>{const e={};m.forEach(t=>{e[t.key]=t.lastEvent.timestamp.getTime()});return e},[m]);const E=y(()=>{if(!I)return null;return m.find(e=>e.key===I)||null},[I,m]);ee(()=>{if(!K)return;const e=u?u:h!==null?E:null;const t=u?z:h;if(!e||t==null)return;const o=[...e.events].sort((w,Z)=>w.timestamp.getTime()-Z.timestamp.getTime());const a=o[t];const s=o[t-1];if(a)K(a);if(s)K(s)},[K,u,z,E,h]);const R=y(()=>{return F.filter(e=>{if(!e.data?.key)return false;if(!b.has(e.storageType))return false;const t=e.data.key;return!Array.from(T).some(o=>t.includes(o))})},[F,T,b]);const Ze=y(()=>It(R),[R]);const f=y(()=>{if(k==="all")return R;return R.filter(e=>e.storageType===k)},[R,k]);const et=i(()=>{return f.map(e=>({key:e.data?.key,action:e.action,value:_(e.data?.value),storageType:e.storageType,timestamp:e.timestamp.toISOString()}))},[f]);const tt=y(()=>f.slice(0,N),[f,N]);const Y=y(()=>Math.max(0,f.length-N),[f.length,N]);const nt=.8;const ot=i(e=>e.id,[]);const Se=i(e=>{const t=m.find(s=>s.key===e.data?.key);if(!t)return;const o=[...t.events].sort((s,w)=>s.timestamp.getTime()-w.timestamp.getTime());const a=o.findIndex(s=>s.timestamp.getTime()===e.timestamp.getTime());A(t.key);x(a>=0?a:0)},[m]);const rt=i(({item:e})=>{const t={key:e.data?.key||"",lastAction:e.action,totalOperations:1,lastEventTimestamp:e.timestamp,storageTypes:new Set([e.storageType]),valueType:O(e.data?.value)};return n(we,{data:t,onPress:()=>Se(e),testID:`buoy-storage-event-${e.id}`})},[Se]);if(!r)return null;const at=Ae?P.modal.root():P.storage.modal();const ve=()=>{if(D){return n(Ft,{ignoredPatterns:T,onTogglePattern:me,onAddPattern:fe,availableKeys:Ue,enabledStorageTypes:b,onToggleStorageType:Je})}if(B==="browser"){if(I&&E){if(h!==null){return n(S,{style:l.contentWrapper,children:n(xe,{conversation:E,selectedEventIndex:h,onEventIndexChange:v,disableInternalFooter:true})})}const t=[...E.events].sort((a,s)=>a.timestamp.getTime()-s.timestamp.getTime());const o=[...t].reverse();return n(Ee,{keyboardShouldPersistTaps:"handled",testID:"buoy-storage-history-list",style:l.flexFill,data:o,keyExtractor:a=>a.id,renderItem:({item:a})=>{const s=t.findIndex(Z=>Z.timestamp.getTime()===a.timestamp.getTime());const w={key:a.data?.key||"",lastAction:a.action,totalOperations:1,lastEventTimestamp:a.timestamp,storageTypes:new Set([a.storageType]),valueType:O(a.data?.value)};return n(we,{data:w,onPress:()=>v(s>=0?s:0),testID:`buoy-storage-history-event-${a.id}`})},contentContainerStyle:l.listContent,ItemSeparatorComponent:()=>n(S,{style:l.separator}),initialNumToRender:20})}return n(Et,{requiredStorageKeys:De,ignoredPatterns:T,onTogglePattern:me,onAddPattern:fe,searchQuery:le,storageDataRef:U,eventCountByKey:Ye,lastWriteByKey:Xe,onViewHistory:je,enabledStorageTypes:b,pinnedKeys:Oe,onTogglePin:$e,applySafeAreaInset:q==="bottomSheet",storageTypeFilter:k,onStorageTypeFilterChange:ge,detailKey:W,onOpenKey:H,onCloseDetail:()=>H(null)})}if(u){return n(S,{style:l.contentWrapper,children:n(xe,{conversation:u,selectedEventIndex:z,onEventIndexChange:x,disableInternalFooter:true})})}const e=n(S,{style:l.eventFilterBar,children:n(Ct,{active:k,onChange:ge,counts:Ze})});if(f.length===0){const t=k!=="all";return p(S,{style:l.flexFill,children:[e,n(gt,{testID:"buoy-storage-events-empty",...!ye?{otto:"paused",title:"Event listener is paused",message:"Press play to start monitoring"}:t?{otto:"filtering",title:`No ${k} events`,message:"Other backends have events \u2014 pick All Types to see them"}:{otto:"listening",title:"No storage events yet",message:"Storage operations will appear here"}})]})}return p(S,{style:l.flexFill,children:[e,n(Ee,{keyboardShouldPersistTaps:"handled",testID:"buoy-storage-events-list",style:l.flexFill,data:tt,renderItem:rt,keyExtractor:ot,onEndReachedThreshold:nt,contentContainerStyle:l.listContent,ListFooterComponent:Y>0?n(S,{style:l.lockedBannerContainer,children:n(wt,{featureName:`${Y} event${Y>1?"s":""} locked`,description:"Upgrade to Pro to unlock full event history"})}):null,initialNumToRender:10,maxToRenderPerBatch:10,windowSize:10})]})};const X=u&&u.events.length>1?n(ke,{conversation:u,selectedEventIndex:z,onEventIndexChange:x,applySafeAreaInset:q==="bottomSheet"}):E&&h!==null&&E.events.length>1?n(ke,{conversation:E,selectedEventIndex:h,onEventIndexChange:v,applySafeAreaInset:q==="bottomSheet"}):null;const st=D?()=>Q(false):h!==null?()=>v(null):I?pe:u?()=>{A(null);x(0)}:V;const Te=D?p(c,{children:[n(c.Navigation,{onBack:()=>Q(false)}),n(c.Content,{title:"Filters"})]}):I?p(c,{children:[n(c.Navigation,{onBack:h!==null?()=>v(null):pe}),n(c.Content,{title:`${I} History`,centered:true})]}):u?p(c,{children:[n(c.Navigation,{onBack:()=>{A(null);x(0)}}),n(c.Content,{title:u.key})]}):W?p(c,{children:[n(c.Navigation,{onBack:()=>H(null)}),n(c.Content,{title:W.key,centered:true,testID:"buoy-storage-detail-title"})]}):p(c,{children:[V&&n(c.Navigation,{onBack:V}),n(c.Content,{title:"",children:j?n(ft,{value:le,onChange:ie,onClear:()=>{ie("");$(false)},placeholder:"Search storage keys...",testID:"buoy-storage-search",autoFocus:true,onSubmitEditing:()=>$(false),returnKeyType:"search",containerStyle:l.headerSearchContainer}):n(ct,{tabs:[{key:"browser",label:"Storage"},{key:"events",label:`Events${f.length>0?` (${f.length})`:""}`}],activeTab:B,testIDPrefix:"buoy-storage-tab",onTabChange:e=>{Ke(e);J(null);v(null);A(null);x(0);H(null)}})}),p(c.Actions,{children:[se&&!j?n(te,{onPress:se,style:l.iconButton,testID:"buoy-storage-refresh",accessibilityLabel:"Refresh storage",accessibilityRole:"button",children:n(pt,{size:14,color:d.color.textSecondary})}):null,n(te,{onPress:Ge,testID:"buoy-storage-filters",accessibilityLabel:"Storage filters",accessibilityRole:"button",style:[l.iconButton,(T.size>0||b.size<3)&&l.activeFilterButton],children:n(yt,{size:14,color:T.size>0||b.size<3?d.color.accent:d.color.textSecondary})}),B==="browser"&&!j&&p(Be,{children:[n(te,{onPress:()=>$(true),testID:"buoy-storage-search-open",accessibilityLabel:"Open search",accessibilityRole:"button",style:l.iconButton,children:n(mt,{size:14,color:d.color.textSecondary})}),n(Ce,{value:Qe,disabled:U.current.length===0,buttonStyle:l.iconButton,testID:"buoy-storage-copy"})]}),B==="events"&&p(Be,{children:[n(Ce,{value:et,disabled:f.length===0,buttonStyle:l.iconButton,testID:"buoy-storage-events-copy"}),n(ht,{isEnabled:ye,onToggle:Ve,accessibilityLabel:"Toggle storage event monitoring",testID:"buoy-storage-power"}),n(St,{onPress:We,buttonStyle:l.iconButton,testID:"buoy-storage-clear-events"})]})]})]});if(Re){return n(Ie,{children:p(S,{style:l.inlineRoot,children:[n(S,{style:l.inlineHeader,...bt,children:Te}),ve(),X]})})}return n(Ie,{children:n(it,{visible:r,onClose:C,onBack:st,onMinimize:Pe,persistenceKey:at,header:{showToggleButton:true,customContent:Te},onModeChange:Le,enablePersistence:true,initialMode:"bottomSheet",enableGlitchEffects:true,styles:{},footer:X,footerHeight:X?68:0,disableScrollWrapper:true,children:ve()})})}export function StorageToolView(r={}){return n(StorageModalWithTabs,{...r,inline:true,visible:true,onClose:()=>{}})}const l=lt.create({inlineRoot:{flex:1,minHeight:0,backgroundColor:"transparent"},inlineHeader:{paddingHorizontal:12,paddingVertical:8,borderBottomWidth:1,borderBottomColor:ut.border.default,backgroundColor:"transparent"},headerSearchContainer:{flex:1},flexFill:{flex:1},iconButton:{width:32,height:32,borderRadius:8,backgroundColor:d.color.buttonSurface,borderWidth:1,borderColor:d.color.border,alignItems:"center",justifyContent:"center"},activeFilterButton:{backgroundColor:d.color.accentSoft,borderColor:d.color.accentBorderStrong},separator:{height:8},listContent:{paddingVertical:6},lockedBannerContainer:{marginTop:8,marginHorizontal:16},eventFilterBar:{paddingHorizontal:12,paddingTop:8,paddingBottom:4},emptyState:{flex:1,justifyContent:"center",alignItems:"center",padding:32},emptyTitle:{color:d.color.text,fontSize:16,fontWeight:"600",marginTop:16,marginBottom:8,fontFamily:L,letterSpacing:.5,textTransform:"uppercase"},emptySubtitle:{color:d.color.textSecondary,fontSize:14,textAlign:"center",fontFamily:L},eventNavigation:{flexDirection:"row",alignItems:"center",gap:8,paddingHorizontal:8},navButton:{padding:4,borderRadius:4},navButtonDisabled:{opacity:.3},eventCounter:{color:d.color.text,fontSize:12,fontWeight:"600",fontFamily:L,paddingHorizontal:8},headerTopRow:{flexDirection:"row",alignItems:"center",gap:8,marginBottom:12},keyNameContainer:{flex:1,flexDirection:"row",alignItems:"center",gap:6,backgroundColor:d.color.surfaceElevated,paddingHorizontal:10,paddingVertical:4,borderRadius:6,borderWidth:1,borderColor:d.color.border,height:28},keyNameText:{flex:1,fontSize:13,fontWeight:"600",color:d.color.accent,fontFamily:L,letterSpacing:.5},contentWrapper:{flex:1}});
@@ -1 +1 @@
1
- "use strict";import R from"./appAsyncStorage";import{classifyPreviewItem as D,createRestoreScope as P,emptyRestoreResult as V,failedRestore as j,isDevToolsStorageKey as c,registerStateSnapshotProvider as x,unionKeys as w,wontApply as v}from"@buoy-gg/shared-ui";import{readMany as B,writeMany as L,removeMany as _}from"./asyncStorageCompat";import{clearAllAppStorage as C}from"./clearAllStorage";import{mmkvInstanceRegistry as $}from"./MMKVInstanceRegistry";import{detectMMKVType as W}from"./mmkvTypeDetection";import{secureStoreRegistry as g}from"./SecureStoreRegistry";function E(n,o){if(n.remove)n.remove(o);else n.delete?.(o)}function H(){return{canCapture:true,canRestore:true}}async function T(){const n=[];const o=(await R.getAllKeys()).filter(i=>!c(i));const a=(await B(o)).filter(i=>i[1]!==null);const s={};for(const{id:i,instance:d}of $.getAll().filter(({id:e})=>!c(e))){try{s[i]=d.getAllKeys().filter(e=>!c(e)).map(e=>{const{value:p,type:l}=W(d,e);if(l==="buffer"){n.push(`mmkv "${i}"/"${e}": ArrayBuffer value not capturable`)}return{key:e,value:p,valueType:l}})}catch{n.push(`mmkv "${i}": unreadable, captured without entries`);s[i]=[]}}const f={};const r=g.getModule();for(const{key:i,options:d}of g.getAll().filter(({key:e})=>!c(e))){if(d.requireAuthentication){n.push(`secure "${i}": biometric-protected, not capturable`);continue}let e=null;if(r){try{e=await r.getItemAsync(i,d)}catch{n.push(`secure "${i}": unreadable, captured as unset`)}}f[i]=e}return{data:{async:a,mmkv:s,secure:f},warnings:n}}async function N(){const{data:n,warnings:o}=await T();return{data:n,warnings:o}}async function U(n,o){const a=n;const s=P(o);const f=s.touch;const r=V();if(!a){return j("empty storage snapshot")}try{const e=(a.async??[]).filter(([t])=>!c(t)&&f(`async:${t}`));const p=new Set(e.map(([t])=>t));const l=(await R.getAllKeys()).filter(t=>!c(t));const h=l.filter(t=>!p.has(t)&&f(`async:${t}`));s.countExcluded((a.async??[]).length-e.length);if(h.length>0)await _(h);if(e.length>0)await L(e);r.applied+=e.length+h.length}catch(e){r.ok=false;r.warnings.push(`asyncstorage restore failed: ${String(e)}`)}for(const[e,p]of Object.entries(a.mmkv??{})){if(c(e))continue;const l=$.get(e);if(!l){r.skipped.push({id:`mmkv:${e}`,reason:"instance not registered"});continue}if(l.instance.isReadOnly){r.skipped.push({id:`mmkv:${e}`,reason:"instance registered read-only"});continue}const{instance:h}=l;try{const t=new Set(p.map(u=>u.key));const m=h.getAllKeys().filter(u=>!c(u));for(const u of m){if(!s.allows(`mmkv:${e}/${u}`))continue;if(!t.has(u)){E(h,u);r.applied+=1}}for(const u of p){if(c(u.key))continue;if(!f(`mmkv:${e}/${u.key}`))continue;if(u.valueType==="buffer"){r.skipped.push({id:`mmkv:${e}/${u.key}`,reason:"ArrayBuffer values cannot be restored"});continue}h.set(u.key,u.value);r.applied+=1}}catch(t){r.ok=false;r.warnings.push(`mmkv "${e}" restore failed: ${String(t)}`)}}const i=a.secure??{};for(const{key:e,options:p}of g.getAll().filter(({key:l})=>!c(l))){if(!s.allows(`secure:${e}`))continue;if(p.requireAuthentication){if(e in i){r.skipped.push({id:`secure:${e}`,reason:"biometric-protected keys are never written"})}continue}try{if(e in i){const l=i[e];if(l===null)await g.deleteValue(e);else await g.setValue(e,l)}else{await g.deleteValue(e)}r.applied+=1}catch(l){r.ok=false;r.warnings.push(`secure "${e}" restore failed: ${String(l)}`)}}for(const e of Object.keys(i)){if(c(e))continue;if(!f(`secure:${e}`))continue;if(!g.getAll().filter(({key:p})=>!c(p)).some(p=>p.key===e)){r.skipped.push({id:`secure:${e}`,reason:"key no longer registered with registerSecureStoreKeys"})}}const d=s.excludedWarning("item(s)");if(d)r.warnings.push(d);return r}async function z(){const n=V();try{await C();n.applied+=1}catch(o){n.ok=false;n.warnings.push(`asyncstorage clear failed: ${String(o)}`)}for(const{id:o,instance:a}of $.getAll().filter(({id:s})=>!c(s))){if(a.isReadOnly){n.skipped.push({id:`mmkv:${o}`,reason:"instance registered read-only"});continue}try{for(const s of a.getAllKeys().filter(f=>!c(f))){E(a,s);n.applied+=1}}catch(s){n.ok=false;n.warnings.push(`mmkv "${o}" clear failed: ${String(s)}`)}}for(const{key:o,options:a}of g.getAll().filter(({key:s})=>!c(s))){if(a.requireAuthentication){n.skipped.push({id:`secure:${o}`,reason:"biometric-protected keys are never written"});continue}try{await g.deleteValue(o);n.applied+=1}catch(s){n.ok=false;n.warnings.push(`secure "${o}" clear failed: ${String(s)}`)}}return n}const F=256*1024;function M(n,o,a,s,f,r){return D({key:n,label:o,oldValue:a,newValue:s,inOld:f,inNew:r},{equal:Object.is,tooLarge:i=>typeof i==="string"&&i.length>F,tooLargeReason:"value too large to render a diff \u2014 restore still applies it"})}async function G(n,o){const a=n??{async:[],mmkv:{},secure:{}};const s=o===void 0;const f=s?(await T()).data:o??{async:[],mmkv:{},secure:{}};const r=[];const i=[];const d=new Map(f.async??[]);const e=new Map(a.async??[]);for(const t of w(d,e)){if(c(t))continue;r.push(M(`async:${t}`,t,d.get(t),e.get(t),d.has(t),e.has(t)))}for(const t of w(f.mmkv,a.mmkv)){if(c(t))continue;const m=s?$.get(t):null;const u=s&&!m;const I=s&&m?.instance.isReadOnly===true;const A=new Map((f.mmkv?.[t]??[]).map(y=>[y.key,y]));const S=new Map((a.mmkv?.[t]??[]).map(y=>[y.key,y]));for(const y of w(A,S)){if(c(y))continue;const O=`mmkv:${t}/${y}`;const q=`${t} \xB7 ${y}`;const b=A.get(y);const K=S.get(y);let k=M(O,q,b?.value,K?.value,A.has(y),S.has(y));if(u){k=v(k,"MMKV instance not registered")}else if(I){k=v(k,"MMKV instance registered read-only")}else if(K?.valueType==="buffer"||b?.valueType==="buffer"){k=v(k,"ArrayBuffer values cannot be restored")}r.push(k)}}const p=f.secure??{};const l=a.secure??{};const h=s?new Map(g.getAll().filter(({key:t})=>!c(t)).map(t=>[t.key,t])):null;for(const t of w(p,l)){if(c(t))continue;let m=M(`secure:${t}`,t,p[t],l[t],t in p,t in l);if(s){const u=h?.get(t);if(!u){m=v(m,"key no longer registered with registerSecureStoreKeys")}else if(u.options.requireAuthentication){m=v(m,"biometric-protected keys are never written")}}r.push(m)}return{items:r,notes:i}}x({id:"storage",label:"Storage",status:H,capture:N,restore:U,clear:z,previewItems:G});
1
+ "use strict";import V from"./appAsyncStorage";import{classifyPreviewItem as L,createRestoreScope as P,emptyRestoreResult as E,failedRestore as B,isDevToolsStorageKey as l,registerStateSnapshotProvider as C,unionKeys as S,wontApply as $}from"@buoy-gg/shared-ui";import{readMany as W,writeMany as _,removeMany as F}from"./asyncStorageCompat";import{clearAllAppStorage as H}from"./clearAllStorage";import{mmkvInstanceRegistry as K}from"./MMKVInstanceRegistry";import{detectMMKVType as N}from"./mmkvTypeDetection";import{secureStoreRegistry as h}from"./SecureStoreRegistry";function T(n,r){if(n.remove)n.remove(r);else n.delete?.(r)}function U(){return{canCapture:true,canRestore:true}}async function x(){const n=[];const r=(await V.getAllKeys()).filter(e=>!l(e));const o=(await W(r)).filter(e=>e[1]!==null);const i={};for(const{id:e,instance:u}of K.getAll().filter(({id:f})=>!l(f))){try{i[e]=u.getAllKeys().filter(f=>!l(f)).map(f=>{const{value:k,type:s}=N(u,f);if(s==="buffer"){n.push(`mmkv "${e}"/"${f}": ArrayBuffer value not capturable`)}return{key:f,value:k,valueType:s}})}catch{n.push(`mmkv "${e}": unreadable, captured without entries`);i[e]=[]}}const c={};const a=h.getModule();for(const{key:e,options:u}of h.getAll().filter(({key:f})=>!l(f))){if(u.requireAuthentication){n.push(`secure "${e}": biometric-protected, not capturable`);continue}let f=null;if(a){try{f=await a.getItemAsync(e,u)}catch{n.push(`secure "${e}": unreadable, captured as unset`)}}c[e]=f}return{data:{async:o,mmkv:i,secure:c},warnings:n}}function A(n){return`mmkv:${n.replace(/%/g,"%25").replace(/\//g,"%2F")}`}function w(n,r){return`${A(n)}/${r}`}function j(n,r){if(!n)return void 0;const o=Object.keys(r).filter(a=>A(a)!==`mmkv:${a}`);if(o.length===0)return[...n];const i=new Set(Object.entries(r).flatMap(([a,e])=>e.map(u=>w(a,u.key))));const c=new Set(n);for(const a of n){if(i.has(a))continue;for(const e of o){const u=`mmkv:${e}/`;if(a.startsWith(u))c.add(w(e,a.slice(u.length)))}}return[...c]}async function z(){const{data:n,warnings:r}=await x();return{data:n,warnings:r}}async function G(n,r){const o=n;const i=o?.mmkv??{};const c=P({excludeKeys:j(r?.excludeKeys,i),includeKeys:j(r?.includeKeys,i)});const a=c.touch;const e=E();if(!o){return B("empty storage snapshot")}try{const s=(o.async??[]).filter(([p])=>!l(p)&&a(`async:${p}`));const m=new Set(s.map(([p])=>p));const t=(await V.getAllKeys()).filter(p=>!l(p));const d=t.filter(p=>!m.has(p)&&a(`async:${p}`));c.countExcluded((o.async??[]).length-s.length);if(d.length>0)await F(d);if(s.length>0)await _(s);e.applied+=s.length+d.length}catch(s){e.ok=false;e.warnings.push(`asyncstorage restore failed: ${String(s)}`)}for(const[s,m]of Object.entries(o.mmkv??{})){if(l(s))continue;const t=K.get(s);if(!t){e.skipped.push({id:A(s),reason:"instance not registered"});continue}if(t.instance.isReadOnly){e.skipped.push({id:A(s),reason:"instance registered read-only"});continue}const{instance:d}=t;try{const p=new Set(m.map(y=>y.key));const M=d.getAllKeys().filter(y=>!l(y));for(const y of M){if(!c.allows(w(s,y)))continue;if(!p.has(y)){T(d,y);e.applied+=1}}for(const y of m){if(l(y.key))continue;if(!a(w(s,y.key)))continue;if(y.valueType==="buffer"){e.skipped.push({id:w(s,y.key),reason:"ArrayBuffer values cannot be restored"});continue}d.set(y.key,y.value);e.applied+=1}}catch(p){e.ok=false;e.warnings.push(`mmkv "${s}" restore failed: ${String(p)}`)}}const u=o.secure??{};const f=o.secure===void 0;for(const{key:s,options:m}of f?[]:h.getAll().filter(({key:t})=>!l(t))){if(!c.allows(`secure:${s}`))continue;if(m.requireAuthentication){if(s in u){e.skipped.push({id:`secure:${s}`,reason:"biometric-protected keys are never written"})}continue}try{if(s in u){const t=u[s];if(t===null)await h.deleteValue(s);else await h.setValue(s,t)}else{await h.deleteValue(s)}e.applied+=1}catch(t){e.ok=false;e.warnings.push(`secure "${s}" restore failed: ${String(t)}`)}}for(const s of Object.keys(u)){if(l(s))continue;if(!a(`secure:${s}`))continue;if(!h.getAll().filter(({key:m})=>!l(m)).some(m=>m.key===s)){e.skipped.push({id:`secure:${s}`,reason:"key no longer registered with registerSecureStoreKeys"})}}const k=c.excludedWarning("item(s)");if(k)e.warnings.push(k);return e}async function J(){const n=E();try{await H();n.applied+=1}catch(r){n.ok=false;n.warnings.push(`asyncstorage clear failed: ${String(r)}`)}for(const{id:r,instance:o}of K.getAll().filter(({id:i})=>!l(i))){if(o.isReadOnly){n.skipped.push({id:A(r),reason:"instance registered read-only"});continue}try{for(const i of o.getAllKeys().filter(c=>!l(c))){T(o,i);n.applied+=1}}catch(i){n.ok=false;n.warnings.push(`mmkv "${r}" clear failed: ${String(i)}`)}}for(const{key:r,options:o}of h.getAll().filter(({key:i})=>!l(i))){if(o.requireAuthentication){n.skipped.push({id:`secure:${r}`,reason:"biometric-protected keys are never written"});continue}try{await h.deleteValue(r);n.applied+=1}catch(i){n.ok=false;n.warnings.push(`secure "${r}" clear failed: ${String(i)}`)}}return n}const Q=256*1024;function R(n,r,o,i,c,a){return L({key:n,label:r,oldValue:o,newValue:i,inOld:c,inNew:a},{equal:Object.is,tooLarge:e=>typeof e==="string"&&e.length>Q,tooLargeReason:"value too large to render a diff \u2014 restore still applies it"})}async function X(n,r){const o=n??{async:[],mmkv:{},secure:{}};const i=r===void 0;const c=i?(await x()).data:r??{async:[],mmkv:{},secure:{}};const a=[];const e=[];const u=new Map(c.async??[]);const f=new Map(o.async??[]);for(const t of S(u,f)){if(l(t))continue;a.push(R(`async:${t}`,t,u.get(t),f.get(t),u.has(t),f.has(t)))}for(const t of S(c.mmkv,o.mmkv)){if(l(t))continue;const d=i?K.get(t):null;const p=i&&!d;const M=i&&d?.instance.isReadOnly===true;const y=new Map((c.mmkv?.[t]??[]).map(g=>[g.key,g]));const b=new Map((o.mmkv?.[t]??[]).map(g=>[g.key,g]));for(const g of S(y,b)){if(l(g))continue;const q=w(t,g);const D=`${t} \xB7 ${g}`;const I=y.get(g);const O=b.get(g);let v=R(q,D,I?.value,O?.value,y.has(g),b.has(g));if(p){v=$(v,"MMKV instance not registered")}else if(M){v=$(v,"MMKV instance registered read-only")}else if(O?.valueType==="buffer"||I?.valueType==="buffer"){v=$(v,"ArrayBuffer values cannot be restored")}a.push(v)}}const k=c.secure??{};const s=o.secure??{};const m=i?new Map(h.getAll().filter(({key:t})=>!l(t)).map(t=>[t.key,t])):null;for(const t of S(k,s)){if(l(t))continue;let d=R(`secure:${t}`,t,k[t],s[t],t in k,t in s);if(i){const p=m?.get(t);if(!p){d=$(d,"key no longer registered with registerSecureStoreKeys")}else if(p.options.requireAuthentication){d=$(d,"biometric-protected keys are never written")}}a.push(d)}return{items:a,notes:e}}C({id:"storage",label:"Storage",status:U,capture:z,restore:G,clear:J,previewItems:X});