@stacksjs/composables 0.75.515 → 0.75.518

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (155) hide show
  1. package/dist/_shared.js +1 -1
  2. package/dist/computedAsync.js +1 -1
  3. package/dist/computedEager.js +1 -1
  4. package/dist/createGlobalState.js +1 -1
  5. package/dist/createSharedComposable.js +1 -1
  6. package/dist/extendRef.js +1 -1
  7. package/dist/formatTimeAgo.js +1 -1
  8. package/dist/isDefined.js +1 -1
  9. package/dist/makeDestructurable.js +1 -1
  10. package/dist/onClickOutside.js +1 -1
  11. package/dist/onKeyStroke.js +1 -1
  12. package/dist/onLongPress.js +1 -1
  13. package/dist/onStartTyping.js +1 -1
  14. package/dist/session-handoff.js +1 -1
  15. package/dist/syncRef.js +1 -1
  16. package/dist/until.js +1 -1
  17. package/dist/useActiveElement.js +1 -1
  18. package/dist/useAnimate.js +1 -1
  19. package/dist/useArrayUtils.js +1 -1
  20. package/dist/useAsyncQueue.js +1 -1
  21. package/dist/useAsyncState.js +1 -1
  22. package/dist/useBase64.js +1 -1
  23. package/dist/useBattery.js +1 -1
  24. package/dist/useBreakpoints.js +1 -1
  25. package/dist/useBroadcastChannel.js +1 -1
  26. package/dist/useBrowserLocation.js +1 -1
  27. package/dist/useClipboard.js +1 -1
  28. package/dist/useClipboardItems.js +1 -1
  29. package/dist/useCloned.js +1 -1
  30. package/dist/useColorMode.js +1 -1
  31. package/dist/useConfirmDialog.js +1 -1
  32. package/dist/useCookieConsent.js +1 -1
  33. package/dist/useCssVar.js +1 -1
  34. package/dist/useCycleList.js +1 -1
  35. package/dist/useDark.js +1 -1
  36. package/dist/useDateFormat.js +1 -1
  37. package/dist/useDebounce.js +1 -1
  38. package/dist/useDebounceFn.js +1 -1
  39. package/dist/useDebouncedRef.js +1 -1
  40. package/dist/useDebouncedRefHistory.js +1 -1
  41. package/dist/useDeviceMotion.js +1 -1
  42. package/dist/useDeviceOrientation.js +1 -1
  43. package/dist/useDevicePixelRatio.js +1 -1
  44. package/dist/useDocumentVisibility.js +1 -1
  45. package/dist/useDraggable.js +1 -1
  46. package/dist/useDropZone.js +1 -1
  47. package/dist/useElementBounding.js +1 -1
  48. package/dist/useElementByPoint.js +1 -1
  49. package/dist/useElementHover.js +1 -1
  50. package/dist/useElementSize.js +1 -1
  51. package/dist/useElementVisibility.js +1 -1
  52. package/dist/useEventBus.js +1 -1
  53. package/dist/useEventListener.js +1 -1
  54. package/dist/useEventSource.js +1 -1
  55. package/dist/useEyeDropper.js +1 -1
  56. package/dist/useFavicon.js +1 -1
  57. package/dist/useFetch.js +1 -1
  58. package/dist/useFileDialog.js +1 -1
  59. package/dist/useFocus.js +1 -1
  60. package/dist/useFocusWithin.js +1 -1
  61. package/dist/useForm.js +1 -1
  62. package/dist/useFps.js +1 -1
  63. package/dist/useFullscreen.js +1 -1
  64. package/dist/useGeolocation.js +1 -1
  65. package/dist/useIdle.js +1 -1
  66. package/dist/useImage.js +1 -1
  67. package/dist/useInfiniteScroll.js +1 -1
  68. package/dist/useIntersectionObserver.js +1 -1
  69. package/dist/useInterval.js +1 -1
  70. package/dist/useIntervalFn.js +1 -1
  71. package/dist/useKeyModifier.js +1 -1
  72. package/dist/useLastChanged.js +1 -1
  73. package/dist/useLocalStorage.js +1 -1
  74. package/dist/useMagicKeys.js +1 -1
  75. package/dist/useManualRefHistory.js +1 -1
  76. package/dist/useMath.js +1 -1
  77. package/dist/useMediaQuery.js +1 -1
  78. package/dist/useMemoize.js +1 -1
  79. package/dist/useMounted.js +1 -1
  80. package/dist/useMouse.js +1 -1
  81. package/dist/useMouseInElement.js +1 -1
  82. package/dist/useMousePressed.js +1 -1
  83. package/dist/useMutationObserver.js +1 -1
  84. package/dist/useNavigatorLanguage.js +1 -1
  85. package/dist/useNetwork.js +1 -1
  86. package/dist/useNow.js +1 -1
  87. package/dist/useObjectUrl.js +1 -1
  88. package/dist/useOffsetPagination.js +1 -1
  89. package/dist/useOnline.js +1 -1
  90. package/dist/usePageLeave.js +1 -1
  91. package/dist/useParallax.js +1 -1
  92. package/dist/useParentElement.js +1 -1
  93. package/dist/usePermission.js +1 -1
  94. package/dist/usePointer.js +1 -1
  95. package/dist/usePointerLock.js +1 -1
  96. package/dist/usePointerSwipe.js +1 -1
  97. package/dist/usePreferredColorScheme.js +1 -1
  98. package/dist/usePreferredContrast.js +1 -1
  99. package/dist/usePreferredLanguages.js +1 -1
  100. package/dist/usePreferredReducedMotion.js +1 -1
  101. package/dist/useQuery.js +1 -1
  102. package/dist/useRafFn.js +1 -1
  103. package/dist/useRefHistory.js +1 -1
  104. package/dist/useResizeObserver.js +1 -1
  105. package/dist/useScreenOrientation.js +1 -1
  106. package/dist/useScreenSafeArea.js +1 -1
  107. package/dist/useScriptTag.js +1 -1
  108. package/dist/useScroll.js +1 -1
  109. package/dist/useScrollLock.js +1 -1
  110. package/dist/useSessionStorage.js +1 -1
  111. package/dist/useShare.js +1 -1
  112. package/dist/useSorted.js +1 -1
  113. package/dist/useStepper.js +1 -1
  114. package/dist/useStorage.js +1 -1
  115. package/dist/useStyleTag.js +1 -1
  116. package/dist/useSupported.js +1 -1
  117. package/dist/useSwipe.js +1 -1
  118. package/dist/useTextDirection.js +1 -1
  119. package/dist/useTextSelection.js +1 -1
  120. package/dist/useTextareaAutosize.js +1 -1
  121. package/dist/useThrottle.js +1 -1
  122. package/dist/useThrottleFn.js +1 -1
  123. package/dist/useThrottledRef.js +1 -1
  124. package/dist/useThrottledRefHistory.js +1 -1
  125. package/dist/useTimeAgo.js +1 -1
  126. package/dist/useTimeout.js +1 -1
  127. package/dist/useTimeoutFn.js +1 -1
  128. package/dist/useTimeoutPoll.js +1 -1
  129. package/dist/useTimestamp.js +1 -1
  130. package/dist/useTitle.js +1 -1
  131. package/dist/useToNumber.js +1 -1
  132. package/dist/useToString.js +1 -1
  133. package/dist/useToggle.js +1 -1
  134. package/dist/useTransition.js +1 -1
  135. package/dist/useUrlSearchParams.js +1 -1
  136. package/dist/useVibrate.js +1 -1
  137. package/dist/useVirtualList.js +1 -1
  138. package/dist/useWakeLock.js +1 -1
  139. package/dist/useWebNotification.js +1 -1
  140. package/dist/useWebSocket.js +1 -1
  141. package/dist/useWebWorker.js +1 -1
  142. package/dist/useWindowFocus.js +1 -1
  143. package/dist/useWindowScroll.js +1 -1
  144. package/dist/useWindowSize.js +1 -1
  145. package/dist/watchArray.js +1 -1
  146. package/dist/watchAtMost.js +1 -1
  147. package/dist/watchDebounced.js +1 -1
  148. package/dist/watchDeep.js +1 -1
  149. package/dist/watchIgnorable.js +1 -1
  150. package/dist/watchOnce.js +1 -1
  151. package/dist/watchPausable.js +1 -1
  152. package/dist/watchThrottled.js +1 -1
  153. package/dist/watchWithFilter.js +1 -1
  154. package/dist/whenever.js +1 -1
  155. package/package.json +2 -2
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";import{unref}from"./_shared";export function useInfiniteScroll(target,onLoadMore,options={}){const{distance=100,direction="bottom"}=options,isLoading=ref(!1);let active=!0;const handler=async()=>{if(!active||isLoading.value)return;const el=unref(target);if(!el)return;let shouldLoad=!1;if(el===window||el===document.documentElement){const scrollTop=window.scrollY||document.documentElement.scrollTop,scrollHeight=document.documentElement.scrollHeight,clientHeight=window.innerHeight;if(direction==="bottom")shouldLoad=scrollHeight-scrollTop-clientHeight<=distance;else if(direction==="top")shouldLoad=scrollTop<=distance}else{const element=el;if(direction==="bottom")shouldLoad=element.scrollHeight-element.scrollTop-element.clientHeight<=distance;else if(direction==="top")shouldLoad=element.scrollTop<=distance;else if(direction==="right")shouldLoad=element.scrollWidth-element.scrollLeft-element.clientWidth<=distance;else if(direction==="left")shouldLoad=element.scrollLeft<=distance}if(shouldLoad){isLoading.value=!0;try{await onLoadMore()}finally{isLoading.value=!1}}},el=unref(target);if(el){const scrollTarget=el===document.documentElement?window:el;scrollTarget.addEventListener("scroll",handler,{passive:!0});try{onUnmounted(()=>{active=!1;scrollTarget.removeEventListener("scroll",handler)})}catch{}}return{isLoading}}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";import{unref}from"./_shared";export function useInfiniteScroll(target,onLoadMore,options={}){const{distance=100,direction="bottom"}=options;const isLoading=ref(false);let active=true;const handler=async()=>{if(!active||isLoading.value)return;const el=unref(target);if(!el)return;let shouldLoad=false;if(el===window||el===document.documentElement){const scrollTop=window.scrollY||document.documentElement.scrollTop;const scrollHeight=document.documentElement.scrollHeight;const clientHeight=window.innerHeight;if(direction==="bottom")shouldLoad=scrollHeight-scrollTop-clientHeight<=distance;else if(direction==="top")shouldLoad=scrollTop<=distance}else{const element=el;if(direction==="bottom")shouldLoad=element.scrollHeight-element.scrollTop-element.clientHeight<=distance;else if(direction==="top")shouldLoad=element.scrollTop<=distance;else if(direction==="right")shouldLoad=element.scrollWidth-element.scrollLeft-element.clientWidth<=distance;else if(direction==="left")shouldLoad=element.scrollLeft<=distance}if(shouldLoad){isLoading.value=true;try{await onLoadMore()}finally{isLoading.value=false}}};const el=unref(target);if(el){const scrollTarget=el===document.documentElement?window:el;scrollTarget.addEventListener("scroll",handler,{passive:true});try{onUnmounted(()=>{active=false;scrollTarget.removeEventListener("scroll",handler)})}catch{}}return{isLoading}}
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";import{unref,noop}from"./_shared";export function useIntersectionObserver(target,callback,options){const isSupported=ref(typeof window<"u"&&"IntersectionObserver"in window);let cleanup=noop;(()=>{cleanup();if(!isSupported.value)return;const el=unref(target);if(!el)return;const observer=new IntersectionObserver(callback,options);observer.observe(el);cleanup=()=>{observer.disconnect();cleanup=noop}})();const stop=()=>{cleanup()};try{onUnmounted(stop)}catch{}return{isSupported,stop}}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";import{unref,noop}from"./_shared";export function useIntersectionObserver(target,callback,options){const isSupported=ref(typeof window!=="undefined"&&"IntersectionObserver"in window);let cleanup=noop;const observe=()=>{cleanup();if(!isSupported.value)return;const el=unref(target);if(!el)return;const observer=new IntersectionObserver(callback,options);observer.observe(el);cleanup=()=>{observer.disconnect();cleanup=noop}};observe();const stop=()=>{cleanup()};try{onUnmounted(stop)}catch{}return{isSupported,stop}}
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";export function useInterval(interval=1000,options={}){const{controls=!1,immediate=!0}=options,counter=ref(0);let intervalId=null;function pause(){if(intervalId!==null){clearInterval(intervalId);intervalId=null}}function resume(){if(intervalId!==null)return;intervalId=setInterval(()=>{counter.value++},interval)}function reset(){counter.value=0;pause();if(immediate)resume()}if(immediate)resume();try{onUnmounted(pause)}catch{}if(controls)return{counter,pause,resume,reset};return counter}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";export function useInterval(interval=1000,options={}){const{controls=false,immediate=true}=options;const counter=ref(0);let intervalId=null;function pause(){if(intervalId!==null){clearInterval(intervalId);intervalId=null}}function resume(){if(intervalId!==null)return;intervalId=setInterval(()=>{counter.value++},interval)}function reset(){counter.value=0;pause();if(immediate){resume()}}if(immediate){resume()}try{onUnmounted(pause)}catch{}if(controls){return{counter,pause,resume,reset}}return counter}
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";export function useIntervalFn(cb,interval=1000,options={}){const{immediate=!0}=options,isActive=ref(!1);let intervalId=null;function pause(){if(intervalId!==null){clearInterval(intervalId);intervalId=null}isActive.value=!1}function resume(){if(intervalId!==null)return;isActive.value=!0;intervalId=setInterval(cb,interval)}if(immediate)resume();try{onUnmounted(pause)}catch{}return{pause,resume,isActive}}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";export function useIntervalFn(cb,interval=1000,options={}){const{immediate=true}=options;const isActive=ref(false);let intervalId=null;function pause(){if(intervalId!==null){clearInterval(intervalId);intervalId=null}isActive.value=false}function resume(){if(intervalId!==null)return;isActive.value=true;intervalId=setInterval(cb,interval)}if(immediate){resume()}try{onUnmounted(pause)}catch{}return{pause,resume,isActive}}
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";export function useKeyModifier(modifier){const state=ref(!1);if(typeof window>"u")return state;const handler=(e)=>{state.value=e.getModifierState(modifier)};window.addEventListener("keydown",handler,{passive:!0});window.addEventListener("keyup",handler,{passive:!0});window.addEventListener("mousedown",handler,{passive:!0});window.addEventListener("mouseup",handler,{passive:!0});try{onUnmounted(()=>{window.removeEventListener("keydown",handler);window.removeEventListener("keyup",handler);window.removeEventListener("mousedown",handler);window.removeEventListener("mouseup",handler)})}catch{}return state}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";export function useKeyModifier(modifier){const state=ref(false);if(typeof window==="undefined")return state;const handler=(e)=>{state.value=e.getModifierState(modifier)};window.addEventListener("keydown",handler,{passive:true});window.addEventListener("keyup",handler,{passive:true});window.addEventListener("mousedown",handler,{passive:true});window.addEventListener("mouseup",handler,{passive:true});try{onUnmounted(()=>{window.removeEventListener("keydown",handler);window.removeEventListener("keyup",handler);window.removeEventListener("mousedown",handler);window.removeEventListener("mouseup",handler)})}catch{}return state}
@@ -1 +1 @@
1
- import{ref,watch}from"@stacksjs/stx";export function useLastChanged(source,options={}){const{initialValue=null}=options,lastChanged=ref(initialValue);watch(source,()=>{lastChanged.value=Date.now()});return lastChanged}
1
+ import{ref,watch}from"@stacksjs/stx";export function useLastChanged(source,options={}){const{initialValue=null}=options;const lastChanged=ref(initialValue);watch(source,()=>{lastChanged.value=Date.now()});return lastChanged}
@@ -1 +1 @@
1
- import{useStorage}from"./useStorage";export function useLocalStorage(key,defaultValue,options){return useStorage(key,defaultValue,typeof localStorage<"u"?localStorage:void 0,options)}
1
+ import{useStorage}from"./useStorage";export function useLocalStorage(key,defaultValue,options){const storage=typeof localStorage!=="undefined"?localStorage:undefined;return useStorage(key,defaultValue,storage,options)}
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";export function useMagicKeys(){const current=ref(new Set),refs=new Map;function getRef(key){const lower=key.toLowerCase();if(!refs.has(lower))refs.set(lower,ref(!1));return refs.get(lower)}function updateCombos(){for(const[key,r]of refs)if(key.includes("+")){const parts=key.split("+").map((p)=>p.trim().toLowerCase());r.value=parts.every((p)=>current.value.has(p))}}if(typeof window<"u"){const onKeyDown=(e)=>{const key=e.key.toLowerCase();current.value.add(key);current.value=new Set(current.value);const r=getRef(key);r.value=!0;if(e.ctrlKey){getRef("ctrl").value=!0;current.value.add("ctrl")}if(e.shiftKey){getRef("shift").value=!0;current.value.add("shift")}if(e.altKey){getRef("alt").value=!0;current.value.add("alt")}if(e.metaKey){getRef("meta").value=!0;current.value.add("meta")}updateCombos()},onKeyUp=(e)=>{const key=e.key.toLowerCase();current.value.delete(key);current.value=new Set(current.value);const r=getRef(key);r.value=!1;if(!e.ctrlKey){getRef("ctrl").value=!1;current.value.delete("ctrl")}if(!e.shiftKey){getRef("shift").value=!1;current.value.delete("shift")}if(!e.altKey){getRef("alt").value=!1;current.value.delete("alt")}if(!e.metaKey){getRef("meta").value=!1;current.value.delete("meta")}updateCombos()};window.addEventListener("keydown",onKeyDown,{passive:!0});window.addEventListener("keyup",onKeyUp,{passive:!0});try{onUnmounted(()=>{window.removeEventListener("keydown",onKeyDown);window.removeEventListener("keyup",onKeyUp)})}catch{}}return new Proxy({current},{get(target,prop){if(prop==="current")return current;return getRef(prop)}})}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";export function useMagicKeys(){const current=ref(new Set);const refs=new Map;function getRef(key){const lower=key.toLowerCase();if(!refs.has(lower)){refs.set(lower,ref(false))}return refs.get(lower)}function updateCombos(){for(const[key,r]of refs){if(key.includes("+")){const parts=key.split("+").map((p)=>p.trim().toLowerCase());r.value=parts.every((p)=>current.value.has(p))}}}if(typeof window!=="undefined"){const onKeyDown=(e)=>{const key=e.key.toLowerCase();current.value.add(key);current.value=new Set(current.value);const r=getRef(key);r.value=true;if(e.ctrlKey){getRef("ctrl").value=true;current.value.add("ctrl")}if(e.shiftKey){getRef("shift").value=true;current.value.add("shift")}if(e.altKey){getRef("alt").value=true;current.value.add("alt")}if(e.metaKey){getRef("meta").value=true;current.value.add("meta")}updateCombos()};const onKeyUp=(e)=>{const key=e.key.toLowerCase();current.value.delete(key);current.value=new Set(current.value);const r=getRef(key);r.value=false;if(!e.ctrlKey){getRef("ctrl").value=false;current.value.delete("ctrl")}if(!e.shiftKey){getRef("shift").value=false;current.value.delete("shift")}if(!e.altKey){getRef("alt").value=false;current.value.delete("alt")}if(!e.metaKey){getRef("meta").value=false;current.value.delete("meta")}updateCombos()};window.addEventListener("keydown",onKeyDown,{passive:true});window.addEventListener("keyup",onKeyUp,{passive:true});try{onUnmounted(()=>{window.removeEventListener("keydown",onKeyDown);window.removeEventListener("keyup",onKeyUp)})}catch{}}return new Proxy({current},{get(target,prop){if(prop==="current")return current;return getRef(prop)}})}
@@ -1 +1 @@
1
- import{computed,ref}from"@stacksjs/stx";function cloneValue(val,shouldClone){if(!shouldClone)return val;if(typeof structuredClone==="function")return structuredClone(val);return JSON.parse(JSON.stringify(val))}export function useManualRefHistory(source,options={}){const{capacity=1/0,clone=!1}=options,undoStack=ref([{snapshot:cloneValue(source.value,clone),timestamp:Date.now()}]),redoStack=ref([]),canUndo=computed(()=>undoStack.value.length>1),canRedo=computed(()=>redoStack.value.length>0),last=computed(()=>{return undoStack.value[undoStack.value.length-1]});function commit(){const record={snapshot:cloneValue(source.value,clone),timestamp:Date.now()};undoStack.value=[...undoStack.value,record];if(capacity!==1/0&&undoStack.value.length>capacity)undoStack.value=undoStack.value.slice(undoStack.value.length-capacity);redoStack.value=[]}function undo(){if(undoStack.value.length<=1)return;const current=undoStack.value[undoStack.value.length-1],newUndoStack=undoStack.value.slice(0,-1);undoStack.value=newUndoStack;if(current)redoStack.value=[...redoStack.value,current];const previous=newUndoStack[newUndoStack.length-1];if(!previous)return;source.value=cloneValue(previous.snapshot,clone)}function redo(){if(redoStack.value.length===0)return;const next=redoStack.value[redoStack.value.length-1];redoStack.value=redoStack.value.slice(0,-1);if(next)undoStack.value=[...undoStack.value,next];if(!next)return;source.value=cloneValue(next.snapshot,clone)}function clear(){undoStack.value=[{snapshot:cloneValue(source.value,clone),timestamp:Date.now()}];redoStack.value=[]}return{history:undoStack,commit,undo,redo,canUndo,canRedo,clear,last}}
1
+ import{computed,ref}from"@stacksjs/stx";function cloneValue(val,shouldClone){if(!shouldClone)return val;if(typeof structuredClone==="function"){return structuredClone(val)}return JSON.parse(JSON.stringify(val))}export function useManualRefHistory(source,options={}){const{capacity=1/0,clone=false}=options;const undoStack=ref([{snapshot:cloneValue(source.value,clone),timestamp:Date.now()}]);const redoStack=ref([]);const canUndo=computed(()=>undoStack.value.length>1);const canRedo=computed(()=>redoStack.value.length>0);const last=computed(()=>{return undoStack.value[undoStack.value.length-1]});function commit(){const record={snapshot:cloneValue(source.value,clone),timestamp:Date.now()};undoStack.value=[...undoStack.value,record];if(capacity!==1/0&&undoStack.value.length>capacity){undoStack.value=undoStack.value.slice(undoStack.value.length-capacity)}redoStack.value=[]}function undo(){if(undoStack.value.length<=1)return;const current=undoStack.value[undoStack.value.length-1];const newUndoStack=undoStack.value.slice(0,-1);undoStack.value=newUndoStack;if(current)redoStack.value=[...redoStack.value,current];const previous=newUndoStack[newUndoStack.length-1];if(!previous)return;source.value=cloneValue(previous.snapshot,clone)}function redo(){if(redoStack.value.length===0)return;const next=redoStack.value[redoStack.value.length-1];redoStack.value=redoStack.value.slice(0,-1);if(next)undoStack.value=[...undoStack.value,next];if(!next)return;source.value=cloneValue(next.snapshot,clone)}function clear(){undoStack.value=[{snapshot:cloneValue(source.value,clone),timestamp:Date.now()}];redoStack.value=[]}return{history:undoStack,commit,undo,redo,canUndo,canRedo,clear,last}}
package/dist/useMath.js CHANGED
@@ -1 +1 @@
1
- import{computed}from"@stacksjs/stx";function unref(val){if(val&&typeof val==="object"&&"value"in val&&"subscribe"in val)return val.value;return val}export function useAbs(value){return computed(()=>Math.abs(unref(value)))}export function useAverage(...args){return computed(()=>{const values=args.map(unref);return values.length?values.reduce((a,b)=>a+b,0)/values.length:0})}export function useCeil(value){return computed(()=>Math.ceil(unref(value)))}export function useClamp(value,min,max){return computed(()=>Math.min(unref(max),Math.max(unref(min),unref(value))))}export function useFloor(value){return computed(()=>Math.floor(unref(value)))}export function useMax(...args){return computed(()=>Math.max(...args.map(unref)))}export function useMin(...args){return computed(()=>Math.min(...args.map(unref)))}export function usePrecision(value,digits=0){return computed(()=>Number(unref(value).toFixed(Math.max(0,Math.min(100,unref(digits))))))}export function useRound(value){return computed(()=>Math.round(unref(value)))}export function useSum(...args){return computed(()=>args.map(unref).reduce((a,b)=>a+b,0))}export function useTrunc(value){return computed(()=>Math.trunc(unref(value)))}export function logicNot(value){return computed(()=>!unref(value))}export function logicOr(...args){return computed(()=>args.some((a)=>unref(a)))}export const or=logicOr;export function and(...args){return computed(()=>args.every((a)=>unref(a)))}
1
+ import{computed}from"@stacksjs/stx";function unref(val){if(val&&typeof val==="object"&&"value"in val&&"subscribe"in val){return val.value}return val}export function useAbs(value){return computed(()=>Math.abs(unref(value)))}export function useAverage(...args){return computed(()=>{const values=args.map(unref);return values.length?values.reduce((a,b)=>a+b,0)/values.length:0})}export function useCeil(value){return computed(()=>Math.ceil(unref(value)))}export function useClamp(value,min,max){return computed(()=>Math.min(unref(max),Math.max(unref(min),unref(value))))}export function useFloor(value){return computed(()=>Math.floor(unref(value)))}export function useMax(...args){return computed(()=>Math.max(...args.map(unref)))}export function useMin(...args){return computed(()=>Math.min(...args.map(unref)))}export function usePrecision(value,digits=0){return computed(()=>Number(unref(value).toFixed(Math.max(0,Math.min(100,unref(digits))))))}export function useRound(value){return computed(()=>Math.round(unref(value)))}export function useSum(...args){return computed(()=>args.map(unref).reduce((a,b)=>a+b,0))}export function useTrunc(value){return computed(()=>Math.trunc(unref(value)))}export function logicNot(value){return computed(()=>!unref(value))}export function logicOr(...args){return computed(()=>args.some((a)=>unref(a)))}export const or=logicOr;export function and(...args){return computed(()=>args.every((a)=>unref(a)))}
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";import{defaultWindow,toValue}from"./_shared";export function useMediaQuery(query){const win=defaultWindow(),matches=ref(!1);if(!win||!win.matchMedia)return matches;const queryStr=toValue(query),mediaQuery=win.matchMedia(queryStr);matches.value=mediaQuery.matches;const handler=(e)=>{matches.value=e.matches};mediaQuery.addEventListener("change",handler);try{onUnmounted(()=>{mediaQuery.removeEventListener("change",handler)})}catch{}return matches}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";import{defaultWindow,toValue}from"./_shared";export function useMediaQuery(query){const win=defaultWindow();const matches=ref(false);if(!win||!win.matchMedia){return matches}const queryStr=toValue(query);const mediaQuery=win.matchMedia(queryStr);matches.value=mediaQuery.matches;const handler=(e)=>{matches.value=e.matches};mediaQuery.addEventListener("change",handler);try{onUnmounted(()=>{mediaQuery.removeEventListener("change",handler)})}catch{}return matches}
@@ -1 +1 @@
1
- export function useMemoize(_fn,getKey){const cache=new Map,keyFn=getKey??((...args)=>JSON.stringify(args)),memoized=function(...args){const key=keyFn(...args);if(cache.has(key))return cache.get(key);const result=_fn(...args);cache.set(key,result);return result};memoized.load=(...args)=>{const key=keyFn(...args),result=_fn(...args);cache.set(key,result);return result};memoized.delete=(...args)=>{const key=keyFn(...args);cache.delete(key)};memoized.clear=()=>{cache.clear()};memoized.cache=cache;return memoized}
1
+ export function useMemoize(_fn,getKey){const cache=new Map;const keyFn=getKey??((...args)=>JSON.stringify(args));const memoized=function(...args){const key=keyFn(...args);if(cache.has(key))return cache.get(key);const result=_fn(...args);cache.set(key,result);return result};memoized.load=(...args)=>{const key=keyFn(...args);const result=_fn(...args);cache.set(key,result);return result};memoized.delete=(...args)=>{const key=keyFn(...args);cache.delete(key)};memoized.clear=()=>{cache.clear()};memoized.cache=cache;return memoized}
@@ -1 +1 @@
1
- import{ref}from"@stacksjs/stx";export function useMounted(){const isMounted=ref(!1);Promise.resolve().then(()=>{isMounted.value=!0});return isMounted}
1
+ import{ref}from"@stacksjs/stx";export function useMounted(){const isMounted=ref(false);Promise.resolve().then(()=>{isMounted.value=true});return isMounted}
package/dist/useMouse.js CHANGED
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";import{noop}from"./_shared";export function useMouse(options){const type=options?.type??"page",touch=options?.touch??!0,initialValue=options?.initialValue??{x:0,y:0},x=ref(initialValue.x),y=ref(initialValue.y),sourceType=ref(null);let cleanup=noop;if(typeof window<"u"){const cleanups=[],getMouseCoords=(event)=>{switch(type){case"page":return{x:event.pageX,y:event.pageY};case"client":return{x:event.clientX,y:event.clientY};case"screen":return{x:event.screenX,y:event.screenY};default:return{x:event.pageX,y:event.pageY}}},mouseHandler=(event)=>{const coords=getMouseCoords(event);x.value=coords.x;y.value=coords.y;sourceType.value="mouse"};window.addEventListener("mousemove",mouseHandler,{passive:!0});cleanups.push(()=>window.removeEventListener("mousemove",mouseHandler));if(touch){const touchHandler=(event)=>{if(event.touches.length>0){const touchEvent=event.touches[0];if(!touchEvent)return;switch(type){case"page":x.value=touchEvent.pageX;y.value=touchEvent.pageY;break;case"client":x.value=touchEvent.clientX;y.value=touchEvent.clientY;break;case"screen":x.value=touchEvent.screenX;y.value=touchEvent.screenY;break}sourceType.value="touch"}};window.addEventListener("touchstart",touchHandler,{passive:!0});window.addEventListener("touchmove",touchHandler,{passive:!0});cleanups.push(()=>{window.removeEventListener("touchstart",touchHandler);window.removeEventListener("touchmove",touchHandler)})}cleanup=()=>{for(const fn of cleanups)fn();cleanups.length=0;cleanup=noop}}try{onUnmounted(()=>cleanup())}catch{}return{x,y,sourceType}}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";import{noop}from"./_shared";export function useMouse(options){const type=options?.type??"page";const touch=options?.touch??true;const initialValue=options?.initialValue??{x:0,y:0};const x=ref(initialValue.x);const y=ref(initialValue.y);const sourceType=ref(null);let cleanup=noop;if(typeof window!=="undefined"){const cleanups=[];const getMouseCoords=(event)=>{switch(type){case"page":return{x:event.pageX,y:event.pageY};case"client":return{x:event.clientX,y:event.clientY};case"screen":return{x:event.screenX,y:event.screenY};default:return{x:event.pageX,y:event.pageY}}};const mouseHandler=(event)=>{const coords=getMouseCoords(event);x.value=coords.x;y.value=coords.y;sourceType.value="mouse"};window.addEventListener("mousemove",mouseHandler,{passive:true});cleanups.push(()=>window.removeEventListener("mousemove",mouseHandler));if(touch){const touchHandler=(event)=>{if(event.touches.length>0){const touchEvent=event.touches[0];if(!touchEvent)return;switch(type){case"page":x.value=touchEvent.pageX;y.value=touchEvent.pageY;break;case"client":x.value=touchEvent.clientX;y.value=touchEvent.clientY;break;case"screen":x.value=touchEvent.screenX;y.value=touchEvent.screenY;break}sourceType.value="touch"}};window.addEventListener("touchstart",touchHandler,{passive:true});window.addEventListener("touchmove",touchHandler,{passive:true});cleanups.push(()=>{window.removeEventListener("touchstart",touchHandler);window.removeEventListener("touchmove",touchHandler)})}cleanup=()=>{for(const fn of cleanups)fn();cleanups.length=0;cleanup=noop}}try{onUnmounted(()=>cleanup())}catch{}return{x,y,sourceType}}
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";import{unref}from"./_shared";export function useMouseInElement(target){const x=ref(0),y=ref(0),elementX=ref(0),elementY=ref(0),elementPositionX=ref(0),elementPositionY=ref(0),elementHeight=ref(0),elementWidth=ref(0),isOutside=ref(!0);if(typeof window>"u")return{x,y,elementX,elementY,elementPositionX,elementPositionY,elementHeight,elementWidth,isOutside};const handler=(event)=>{x.value=event.pageX;y.value=event.pageY;const el=unref(target);if(!el){isOutside.value=!0;return}const rect=el.getBoundingClientRect();elementPositionX.value=rect.left+window.scrollX;elementPositionY.value=rect.top+window.scrollY;elementHeight.value=rect.height;elementWidth.value=rect.width;elementX.value=event.pageX-elementPositionX.value;elementY.value=event.pageY-elementPositionY.value;isOutside.value=elementX.value<0||elementY.value<0||elementX.value>elementWidth.value||elementY.value>elementHeight.value};window.addEventListener("mousemove",handler,{passive:!0});try{onUnmounted(()=>{window.removeEventListener("mousemove",handler)})}catch{}return{x,y,elementX,elementY,elementPositionX,elementPositionY,elementHeight,elementWidth,isOutside}}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";import{unref}from"./_shared";export function useMouseInElement(target){const x=ref(0);const y=ref(0);const elementX=ref(0);const elementY=ref(0);const elementPositionX=ref(0);const elementPositionY=ref(0);const elementHeight=ref(0);const elementWidth=ref(0);const isOutside=ref(true);if(typeof window==="undefined")return{x,y,elementX,elementY,elementPositionX,elementPositionY,elementHeight,elementWidth,isOutside};const handler=(event)=>{x.value=event.pageX;y.value=event.pageY;const el=unref(target);if(!el){isOutside.value=true;return}const rect=el.getBoundingClientRect();elementPositionX.value=rect.left+window.scrollX;elementPositionY.value=rect.top+window.scrollY;elementHeight.value=rect.height;elementWidth.value=rect.width;elementX.value=event.pageX-elementPositionX.value;elementY.value=event.pageY-elementPositionY.value;isOutside.value=elementX.value<0||elementY.value<0||elementX.value>elementWidth.value||elementY.value>elementHeight.value};window.addEventListener("mousemove",handler,{passive:true});try{onUnmounted(()=>{window.removeEventListener("mousemove",handler)})}catch{}return{x,y,elementX,elementY,elementPositionX,elementPositionY,elementHeight,elementWidth,isOutside}}
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";import{unref}from"./_shared";export function useMousePressed(target){const pressed=ref(!1),sourceType=ref(null);if(typeof window>"u")return{pressed,sourceType};const el=unref(target)??window,onMouseDown=()=>{pressed.value=!0;sourceType.value="mouse"},onTouchStart=()=>{pressed.value=!0;sourceType.value="touch"},onUp=()=>{pressed.value=!1};el.addEventListener("mousedown",onMouseDown,{passive:!0});el.addEventListener("touchstart",onTouchStart,{passive:!0});window.addEventListener("mouseup",onUp,{passive:!0});window.addEventListener("touchend",onUp,{passive:!0});window.addEventListener("touchcancel",onUp,{passive:!0});try{onUnmounted(()=>{el.removeEventListener("mousedown",onMouseDown);el.removeEventListener("touchstart",onTouchStart);window.removeEventListener("mouseup",onUp);window.removeEventListener("touchend",onUp);window.removeEventListener("touchcancel",onUp)})}catch{}return{pressed,sourceType}}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";import{unref}from"./_shared";export function useMousePressed(target){const pressed=ref(false);const sourceType=ref(null);if(typeof window==="undefined")return{pressed,sourceType};const el=unref(target)??window;const onMouseDown=()=>{pressed.value=true;sourceType.value="mouse"};const onTouchStart=()=>{pressed.value=true;sourceType.value="touch"};const onUp=()=>{pressed.value=false};el.addEventListener("mousedown",onMouseDown,{passive:true});el.addEventListener("touchstart",onTouchStart,{passive:true});window.addEventListener("mouseup",onUp,{passive:true});window.addEventListener("touchend",onUp,{passive:true});window.addEventListener("touchcancel",onUp,{passive:true});try{onUnmounted(()=>{el.removeEventListener("mousedown",onMouseDown);el.removeEventListener("touchstart",onTouchStart);window.removeEventListener("mouseup",onUp);window.removeEventListener("touchend",onUp);window.removeEventListener("touchcancel",onUp)})}catch{}return{pressed,sourceType}}
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";import{unref,noop}from"./_shared";export function useMutationObserver(target,callback,options){const isSupported=ref(typeof window<"u"&&"MutationObserver"in window);let cleanup=noop;(()=>{cleanup();if(!isSupported.value)return;const el=unref(target);if(!el)return;const observer=new MutationObserver(callback);observer.observe(el,options??{childList:!0,subtree:!0});cleanup=()=>{observer.disconnect();cleanup=noop}})();const stop=()=>{cleanup()};try{onUnmounted(stop)}catch{}return{isSupported,stop}}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";import{unref,noop}from"./_shared";export function useMutationObserver(target,callback,options){const isSupported=ref(typeof window!=="undefined"&&"MutationObserver"in window);let cleanup=noop;const observe=()=>{cleanup();if(!isSupported.value)return;const el=unref(target);if(!el)return;const observer=new MutationObserver(callback);observer.observe(el,options??{childList:true,subtree:true});cleanup=()=>{observer.disconnect();cleanup=noop}};observe();const stop=()=>{cleanup()};try{onUnmounted(stop)}catch{}return{isSupported,stop}}
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";export function useNavigatorLanguage(){const isSupported=ref(typeof navigator<"u"&&"language"in navigator),language=ref(isSupported.value?navigator.language:"");if(typeof window<"u"){const handler=()=>{if(isSupported.value)language.value=navigator.language};window.addEventListener("languagechange",handler,{passive:!0});try{onUnmounted(()=>{window.removeEventListener("languagechange",handler)})}catch{}}return{language,isSupported}}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";export function useNavigatorLanguage(){const isSupported=ref(typeof navigator!=="undefined"&&"language"in navigator);const language=ref(isSupported.value?navigator.language:"");if(typeof window!=="undefined"){const handler=()=>{if(isSupported.value)language.value=navigator.language};window.addEventListener("languagechange",handler,{passive:true});try{onUnmounted(()=>{window.removeEventListener("languagechange",handler)})}catch{}}return{language,isSupported}}
@@ -1 +1 @@
1
- import"./types/dom-vendor";import{onUnmounted,ref}from"@stacksjs/stx";export function useNetwork(){const isSupported=ref(typeof navigator<"u"&&"connection"in navigator),isOnline=ref(typeof navigator<"u"?navigator.onLine:!0),offlineAt=ref(void 0),onlineAt=ref(void 0),downlink=ref(void 0),downlinkMax=ref(void 0),effectiveType=ref(void 0),rtt=ref(void 0),saveData=ref(void 0),type=ref(void 0);function updateNetworkInfo(){if(!isSupported.value)return;const conn=navigator.connection;if(conn){downlink.value=conn.downlink;downlinkMax.value=conn.downlinkMax;effectiveType.value=conn.effectiveType;rtt.value=conn.rtt;saveData.value=conn.saveData;type.value=conn.type}}updateNetworkInfo();if(typeof window<"u"){const onOnline=()=>{isOnline.value=!0;onlineAt.value=Date.now()},onOffline=()=>{isOnline.value=!1;offlineAt.value=Date.now()};window.addEventListener("online",onOnline);window.addEventListener("offline",onOffline);try{onUnmounted(()=>{window.removeEventListener("online",onOnline);window.removeEventListener("offline",onOffline)})}catch{}if(isSupported.value){const conn=navigator.connection;if(conn?.addEventListener){conn.addEventListener("change",updateNetworkInfo);try{onUnmounted(()=>{conn.removeEventListener?.("change",updateNetworkInfo)})}catch{}}}}return{isSupported,isOnline,offlineAt,onlineAt,downlink,downlinkMax,effectiveType,rtt,saveData,type}}
1
+ import"./types/dom-vendor";import{onUnmounted,ref}from"@stacksjs/stx";export function useNetwork(){const isSupported=ref(typeof navigator!=="undefined"&&"connection"in navigator);const isOnline=ref(typeof navigator!=="undefined"?navigator.onLine:true);const offlineAt=ref(undefined);const onlineAt=ref(undefined);const downlink=ref(undefined);const downlinkMax=ref(undefined);const effectiveType=ref(undefined);const rtt=ref(undefined);const saveData=ref(undefined);const type=ref(undefined);function updateNetworkInfo(){if(!isSupported.value)return;const conn=navigator.connection;if(conn){downlink.value=conn.downlink;downlinkMax.value=conn.downlinkMax;effectiveType.value=conn.effectiveType;rtt.value=conn.rtt;saveData.value=conn.saveData;type.value=conn.type}}updateNetworkInfo();if(typeof window!=="undefined"){const onOnline=()=>{isOnline.value=true;onlineAt.value=Date.now()};const onOffline=()=>{isOnline.value=false;offlineAt.value=Date.now()};window.addEventListener("online",onOnline);window.addEventListener("offline",onOffline);try{onUnmounted(()=>{window.removeEventListener("online",onOnline);window.removeEventListener("offline",onOffline)})}catch{}if(isSupported.value){const conn=navigator.connection;if(conn?.addEventListener){conn.addEventListener("change",updateNetworkInfo);try{onUnmounted(()=>{conn.removeEventListener?.("change",updateNetworkInfo)})}catch{}}}}return{isSupported,isOnline,offlineAt,onlineAt,downlink,downlinkMax,effectiveType,rtt,saveData,type}}
package/dist/useNow.js CHANGED
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";export function useNow(options){const interval=options?.interval??1000,now=ref(new Date),timer=setInterval(()=>{now.value=new Date},interval);try{onUnmounted(()=>clearInterval(timer))}catch{}return now}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";export function useNow(options){const interval=options?.interval??1000;const now=ref(new Date);const timer=setInterval(()=>{now.value=new Date},interval);try{onUnmounted(()=>clearInterval(timer))}catch{}return now}
@@ -1 +1 @@
1
- import{onUnmounted,ref,watch}from"@stacksjs/stx";export function useObjectUrl(source){const url=ref(void 0);function release(){if(url.value){URL.revokeObjectURL(url.value);url.value=void 0}}function update(val){release();if(val)url.value=URL.createObjectURL(val)}update(source.value);watch(source,(val)=>{update(val)});try{onUnmounted(()=>release())}catch{}return url}
1
+ import{onUnmounted,ref,watch}from"@stacksjs/stx";export function useObjectUrl(source){const url=ref(undefined);function release(){if(url.value){URL.revokeObjectURL(url.value);url.value=undefined}}function update(val){release();if(val)url.value=URL.createObjectURL(val)}update(source.value);watch(source,(val)=>{update(val)});try{onUnmounted(()=>release())}catch{}return url}
@@ -1 +1 @@
1
- import{ref,watch}from"@stacksjs/stx";export function useOffsetPagination(options={}){const{total:totalOption,pageSize=10,page=1,onPageChange,onPageSizeChange}=options,currentPage=ref(page),currentPageSize=ref(pageSize),totalItems=typeof totalOption==="object"&&totalOption&&"value"in totalOption?totalOption:ref(typeof totalOption==="number"?totalOption:0),pageCount=ref(Math.max(1,Math.ceil(totalItems.value/currentPageSize.value))),isFirstPage=ref(currentPage.value<=1),isLastPage=ref(currentPage.value>=pageCount.value);function updateComputed(){pageCount.value=Math.max(1,Math.ceil(totalItems.value/currentPageSize.value));isFirstPage.value=currentPage.value<=1;isLastPage.value=currentPage.value>=pageCount.value}watch(currentPage,()=>{updateComputed();onPageChange?.({currentPage:currentPage.value,currentPageSize:currentPageSize.value})});watch(currentPageSize,()=>{currentPage.value=1;updateComputed();onPageSizeChange?.({currentPage:currentPage.value,currentPageSize:currentPageSize.value})});watch(totalItems,()=>{updateComputed()});function prev(){if(currentPage.value>1)currentPage.value--}function next(){if(currentPage.value<pageCount.value)currentPage.value++}updateComputed();return{currentPage,currentPageSize,pageCount,isFirstPage,isLastPage,prev,next}}
1
+ import{ref,watch}from"@stacksjs/stx";export function useOffsetPagination(options={}){const{total:totalOption,pageSize=10,page=1,onPageChange,onPageSizeChange}=options;const currentPage=ref(page);const currentPageSize=ref(pageSize);const totalItems=typeof totalOption==="object"&&totalOption&&"value"in totalOption?totalOption:ref(typeof totalOption==="number"?totalOption:0);const pageCount=ref(Math.max(1,Math.ceil(totalItems.value/currentPageSize.value)));const isFirstPage=ref(currentPage.value<=1);const isLastPage=ref(currentPage.value>=pageCount.value);function updateComputed(){pageCount.value=Math.max(1,Math.ceil(totalItems.value/currentPageSize.value));isFirstPage.value=currentPage.value<=1;isLastPage.value=currentPage.value>=pageCount.value}watch(currentPage,()=>{updateComputed();onPageChange?.({currentPage:currentPage.value,currentPageSize:currentPageSize.value})});watch(currentPageSize,()=>{currentPage.value=1;updateComputed();onPageSizeChange?.({currentPage:currentPage.value,currentPageSize:currentPageSize.value})});watch(totalItems,()=>{updateComputed()});function prev(){if(currentPage.value>1)currentPage.value--}function next(){if(currentPage.value<pageCount.value)currentPage.value++}updateComputed();return{currentPage,currentPageSize,pageCount,isFirstPage,isLastPage,prev,next}}
package/dist/useOnline.js CHANGED
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";export function useOnline(){const isOnline=ref(typeof navigator<"u"?navigator.onLine:!0);if(typeof window<"u"){const onOnline=()=>{isOnline.value=!0},onOffline=()=>{isOnline.value=!1};window.addEventListener("online",onOnline);window.addEventListener("offline",onOffline);try{onUnmounted(()=>{window.removeEventListener("online",onOnline);window.removeEventListener("offline",onOffline)})}catch{}}return isOnline}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";export function useOnline(){const isOnline=ref(typeof navigator!=="undefined"?navigator.onLine:true);if(typeof window!=="undefined"){const onOnline=()=>{isOnline.value=true};const onOffline=()=>{isOnline.value=false};window.addEventListener("online",onOnline);window.addEventListener("offline",onOffline);try{onUnmounted(()=>{window.removeEventListener("online",onOnline);window.removeEventListener("offline",onOffline)})}catch{}}return isOnline}
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";import{noop}from"./_shared";export function usePageLeave(){const isLeft=ref(!1);let cleanup=noop;if(typeof document<"u"){const cleanups=[],onLeave=(event)=>{if(event.clientY<=0||event.clientX<=0||event.clientX>=(typeof window<"u"?window.innerWidth:0)||event.clientY>=(typeof window<"u"?window.innerHeight:0))isLeft.value=!0},onEnter=()=>{isLeft.value=!1};document.documentElement.addEventListener("mouseleave",onLeave);document.documentElement.addEventListener("mouseenter",onEnter);cleanups.push(()=>document.documentElement.removeEventListener("mouseleave",onLeave),()=>document.documentElement.removeEventListener("mouseenter",onEnter));cleanup=()=>{for(const fn of cleanups)fn();cleanups.length=0;cleanup=noop}}try{onUnmounted(()=>cleanup())}catch{}return isLeft}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";import{noop}from"./_shared";export function usePageLeave(){const isLeft=ref(false);let cleanup=noop;if(typeof document!=="undefined"){const cleanups=[];const onLeave=(event)=>{if(event.clientY<=0||event.clientX<=0||event.clientX>=(typeof window!=="undefined"?window.innerWidth:0)||event.clientY>=(typeof window!=="undefined"?window.innerHeight:0)){isLeft.value=true}};const onEnter=()=>{isLeft.value=false};document.documentElement.addEventListener("mouseleave",onLeave);document.documentElement.addEventListener("mouseenter",onEnter);cleanups.push(()=>document.documentElement.removeEventListener("mouseleave",onLeave),()=>document.documentElement.removeEventListener("mouseenter",onEnter));cleanup=()=>{for(const fn of cleanups)fn();cleanups.length=0;cleanup=noop}}try{onUnmounted(()=>cleanup())}catch{}return isLeft}
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";import{unref}from"./_shared";export function useParallax(target,options={}){const tilt=ref(0),roll=ref(0),source=ref("mouse");if(typeof window>"u")return{tilt,roll,source};const mouseHandler=(e)=>{const el=unref(target);if(!el)return;const rect=el.getBoundingClientRect(),centerX=rect.left+rect.width/2,centerY=rect.top+rect.height/2;tilt.value=(e.clientX-centerX)/(rect.width/2)*0.5;roll.value=(e.clientY-centerY)/(rect.height/2)*0.5;source.value="mouse"};window.addEventListener("mousemove",mouseHandler,{passive:!0});const orientationHandler=(e)=>{if(e.gamma!==null&&e.beta!==null){const tiltVal=e.gamma/90,rollVal=(e.beta-45)/90;tilt.value=options.deviceOrientationTiltAdjust?.(tiltVal)??tiltVal*0.5;roll.value=options.deviceOrientationRollAdjust?.(rollVal)??rollVal*0.5;source.value="deviceOrientation"}};window.addEventListener("deviceorientation",orientationHandler,{passive:!0});try{onUnmounted(()=>{window.removeEventListener("mousemove",mouseHandler);window.removeEventListener("deviceorientation",orientationHandler)})}catch{}return{tilt,roll,source}}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";import{unref}from"./_shared";export function useParallax(target,options={}){const tilt=ref(0);const roll=ref(0);const source=ref("mouse");if(typeof window==="undefined")return{tilt,roll,source};const mouseHandler=(e)=>{const el=unref(target);if(!el)return;const rect=el.getBoundingClientRect();const centerX=rect.left+rect.width/2;const centerY=rect.top+rect.height/2;tilt.value=(e.clientX-centerX)/(rect.width/2)*0.5;roll.value=(e.clientY-centerY)/(rect.height/2)*0.5;source.value="mouse"};window.addEventListener("mousemove",mouseHandler,{passive:true});const orientationHandler=(e)=>{if(e.gamma!==null&&e.beta!==null){const tiltVal=e.gamma/90;const rollVal=(e.beta-45)/90;tilt.value=options.deviceOrientationTiltAdjust?.(tiltVal)??tiltVal*0.5;roll.value=options.deviceOrientationRollAdjust?.(rollVal)??rollVal*0.5;source.value="deviceOrientation"}};window.addEventListener("deviceorientation",orientationHandler,{passive:true});try{onUnmounted(()=>{window.removeEventListener("mousemove",mouseHandler);window.removeEventListener("deviceorientation",orientationHandler)})}catch{}return{tilt,roll,source}}
@@ -1 +1 @@
1
- import{ref}from"@stacksjs/stx";import{unref}from"./_shared";export function useParentElement(element){const parent=ref(null),el=unref(element);if(el)parent.value=el.parentElement;return parent}
1
+ import{ref}from"@stacksjs/stx";import{unref}from"./_shared";export function useParentElement(element){const parent=ref(null);const el=unref(element);if(el)parent.value=el.parentElement;return parent}
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";export function usePermission(permissionName){const isSupported=ref(typeof navigator<"u"&&"permissions"in navigator),state=ref("prompt");if(!isSupported.value)return{state,isSupported};let permissionStatus=null;navigator.permissions.query({name:permissionName}).then((status)=>{permissionStatus=status;state.value=status.state;const handler=()=>{state.value=status.state};status.addEventListener("change",handler);try{onUnmounted(()=>{status.removeEventListener("change",handler)})}catch{}}).catch(()=>{});return{state,isSupported}}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";export function usePermission(permissionName){const isSupported=ref(typeof navigator!=="undefined"&&"permissions"in navigator);const state=ref("prompt");if(!isSupported.value)return{state,isSupported};let permissionStatus=null;navigator.permissions.query({name:permissionName}).then((status)=>{permissionStatus=status;state.value=status.state;const handler=()=>{state.value=status.state};status.addEventListener("change",handler);try{onUnmounted(()=>{status.removeEventListener("change",handler)})}catch{}}).catch(()=>{});return{state,isSupported}}
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";export function usePointer(target){const x=ref(0),y=ref(0),pointerId=ref(0),pressure=ref(0),tiltX=ref(0),tiltY=ref(0),pointerType=ref(""),isInside=ref(!1);if(typeof window>"u")return{isInside,x,y,pointerId,pressure,tiltX,tiltY,pointerType};const el=target??window,handler=(e)=>{x.value=e.pageX;y.value=e.pageY;pointerId.value=e.pointerId;pressure.value=e.pressure;tiltX.value=e.tiltX;tiltY.value=e.tiltY;pointerType.value=e.pointerType},onEnter=()=>{isInside.value=!0},onLeave=()=>{isInside.value=!1};el.addEventListener("pointermove",handler,{passive:!0});el.addEventListener("pointerdown",handler,{passive:!0});el.addEventListener("pointerenter",onEnter,{passive:!0});el.addEventListener("pointerleave",onLeave,{passive:!0});try{onUnmounted(()=>{el.removeEventListener("pointermove",handler);el.removeEventListener("pointerdown",handler);el.removeEventListener("pointerenter",onEnter);el.removeEventListener("pointerleave",onLeave)})}catch{}return{isInside,x,y,pointerId,pressure,tiltX,tiltY,pointerType}}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";export function usePointer(target){const x=ref(0);const y=ref(0);const pointerId=ref(0);const pressure=ref(0);const tiltX=ref(0);const tiltY=ref(0);const pointerType=ref("");const isInside=ref(false);if(typeof window==="undefined")return{isInside,x,y,pointerId,pressure,tiltX,tiltY,pointerType};const el=target??window;const handler=(e)=>{x.value=e.pageX;y.value=e.pageY;pointerId.value=e.pointerId;pressure.value=e.pressure;tiltX.value=e.tiltX;tiltY.value=e.tiltY;pointerType.value=e.pointerType};const onEnter=()=>{isInside.value=true};const onLeave=()=>{isInside.value=false};el.addEventListener("pointermove",handler,{passive:true});el.addEventListener("pointerdown",handler,{passive:true});el.addEventListener("pointerenter",onEnter,{passive:true});el.addEventListener("pointerleave",onLeave,{passive:true});try{onUnmounted(()=>{el.removeEventListener("pointermove",handler);el.removeEventListener("pointerdown",handler);el.removeEventListener("pointerenter",onEnter);el.removeEventListener("pointerleave",onLeave)})}catch{}return{isInside,x,y,pointerId,pressure,tiltX,tiltY,pointerType}}
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";import{unref}from"./_shared";export function usePointerLock(target){const isSupported=ref(typeof document<"u"&&"pointerLockElement"in document),isLocked=ref(!1),element=ref(null);if(typeof document<"u"){const handler=()=>{isLocked.value=!!document.pointerLockElement;element.value=document.pointerLockElement};document.addEventListener("pointerlockchange",handler);document.addEventListener("pointerlockerror",handler);try{onUnmounted(()=>{document.removeEventListener("pointerlockchange",handler);document.removeEventListener("pointerlockerror",handler)})}catch{}}async function lock(el){if(!isSupported.value)return;const targetEl=el??unref(target);if(targetEl)await targetEl.requestPointerLock()}function unlock(){if(!isSupported.value)return;if(document.pointerLockElement)document.exitPointerLock()}return{isSupported,isLocked,lock,unlock,element}}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";import{unref}from"./_shared";export function usePointerLock(target){const isSupported=ref(typeof document!=="undefined"&&"pointerLockElement"in document);const isLocked=ref(false);const element=ref(null);if(typeof document!=="undefined"){const handler=()=>{isLocked.value=!!document.pointerLockElement;element.value=document.pointerLockElement};document.addEventListener("pointerlockchange",handler);document.addEventListener("pointerlockerror",handler);try{onUnmounted(()=>{document.removeEventListener("pointerlockchange",handler);document.removeEventListener("pointerlockerror",handler)})}catch{}}async function lock(el){if(!isSupported.value)return;const targetEl=el??unref(target);if(targetEl)await targetEl.requestPointerLock()}function unlock(){if(!isSupported.value)return;if(document.pointerLockElement)document.exitPointerLock()}return{isSupported,isLocked,lock,unlock,element}}
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";import{unref}from"./_shared";export function usePointerSwipe(target,options={}){const{threshold=50,onSwipe,onSwipeEnd}=options,isSwiping=ref(!1),direction=ref("none"),distanceX=ref(0),distanceY=ref(0),posStart=ref({x:0,y:0}),posEnd=ref({x:0,y:0});if(typeof window>"u")return{isSwiping,direction,distanceX,distanceY,posStart,posEnd};const el=unref(target);if(!el)return{isSwiping,direction,distanceX,distanceY,posStart,posEnd};const onPointerDown=(e)=>{isSwiping.value=!0;direction.value="none";posStart.value={x:e.clientX,y:e.clientY};posEnd.value={x:e.clientX,y:e.clientY};distanceX.value=0;distanceY.value=0;el.setPointerCapture(e.pointerId)},onPointerMove=(e)=>{if(!isSwiping.value)return;posEnd.value={x:e.clientX,y:e.clientY};distanceX.value=posEnd.value.x-posStart.value.x;distanceY.value=posEnd.value.y-posStart.value.y;const absX=Math.abs(distanceX.value),absY=Math.abs(distanceY.value);if(absX>absY)direction.value=distanceX.value>0?"right":"left";else if(absY>absX)direction.value=distanceY.value>0?"down":"up"},onPointerUp=(e)=>{if(!isSwiping.value)return;isSwiping.value=!1;if(Math.max(Math.abs(distanceX.value),Math.abs(distanceY.value))>=threshold){onSwipe?.(direction.value);onSwipeEnd?.(e,direction.value)}else{direction.value="none";onSwipeEnd?.(e,"none")}};el.addEventListener("pointerdown",onPointerDown);el.addEventListener("pointermove",onPointerMove);el.addEventListener("pointerup",onPointerUp);try{onUnmounted(()=>{el.removeEventListener("pointerdown",onPointerDown);el.removeEventListener("pointermove",onPointerMove);el.removeEventListener("pointerup",onPointerUp)})}catch{}return{isSwiping,direction,distanceX,distanceY,posStart,posEnd}}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";import{unref}from"./_shared";export function usePointerSwipe(target,options={}){const{threshold=50,onSwipe,onSwipeEnd}=options;const isSwiping=ref(false);const direction=ref("none");const distanceX=ref(0);const distanceY=ref(0);const posStart=ref({x:0,y:0});const posEnd=ref({x:0,y:0});if(typeof window==="undefined")return{isSwiping,direction,distanceX,distanceY,posStart,posEnd};const el=unref(target);if(!el)return{isSwiping,direction,distanceX,distanceY,posStart,posEnd};const onPointerDown=(e)=>{isSwiping.value=true;direction.value="none";posStart.value={x:e.clientX,y:e.clientY};posEnd.value={x:e.clientX,y:e.clientY};distanceX.value=0;distanceY.value=0;el.setPointerCapture(e.pointerId)};const onPointerMove=(e)=>{if(!isSwiping.value)return;posEnd.value={x:e.clientX,y:e.clientY};distanceX.value=posEnd.value.x-posStart.value.x;distanceY.value=posEnd.value.y-posStart.value.y;const absX=Math.abs(distanceX.value);const absY=Math.abs(distanceY.value);if(absX>absY)direction.value=distanceX.value>0?"right":"left";else if(absY>absX)direction.value=distanceY.value>0?"down":"up"};const onPointerUp=(e)=>{if(!isSwiping.value)return;isSwiping.value=false;const maxDist=Math.max(Math.abs(distanceX.value),Math.abs(distanceY.value));if(maxDist>=threshold){onSwipe?.(direction.value);onSwipeEnd?.(e,direction.value)}else{direction.value="none";onSwipeEnd?.(e,"none")}};el.addEventListener("pointerdown",onPointerDown);el.addEventListener("pointermove",onPointerMove);el.addEventListener("pointerup",onPointerUp);try{onUnmounted(()=>{el.removeEventListener("pointerdown",onPointerDown);el.removeEventListener("pointermove",onPointerMove);el.removeEventListener("pointerup",onPointerUp)})}catch{}return{isSwiping,direction,distanceX,distanceY,posStart,posEnd}}
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";export function usePreferredColorScheme(){const scheme=ref("no-preference");if(typeof window>"u"||!window.matchMedia)return scheme;const dark=window.matchMedia("(prefers-color-scheme: dark)"),light=window.matchMedia("(prefers-color-scheme: light)");function update(){if(dark.matches)scheme.value="dark";else if(light.matches)scheme.value="light";else scheme.value="no-preference"}update();dark.addEventListener("change",update);light.addEventListener("change",update);try{onUnmounted(()=>{dark.removeEventListener("change",update);light.removeEventListener("change",update)})}catch{}return scheme}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";export function usePreferredColorScheme(){const scheme=ref("no-preference");if(typeof window==="undefined"||!window.matchMedia)return scheme;const dark=window.matchMedia("(prefers-color-scheme: dark)");const light=window.matchMedia("(prefers-color-scheme: light)");function update(){if(dark.matches)scheme.value="dark";else if(light.matches)scheme.value="light";else scheme.value="no-preference"}update();dark.addEventListener("change",update);light.addEventListener("change",update);try{onUnmounted(()=>{dark.removeEventListener("change",update);light.removeEventListener("change",update)})}catch{}return scheme}
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";export function usePreferredContrast(){const contrast=ref("no-preference");if(typeof window>"u"||!window.matchMedia)return contrast;const more=window.matchMedia("(prefers-contrast: more)"),less=window.matchMedia("(prefers-contrast: less)"),custom=window.matchMedia("(prefers-contrast: custom)");function update(){if(more.matches)contrast.value="more";else if(less.matches)contrast.value="less";else if(custom.matches)contrast.value="custom";else contrast.value="no-preference"}update();more.addEventListener("change",update);less.addEventListener("change",update);custom.addEventListener("change",update);try{onUnmounted(()=>{more.removeEventListener("change",update);less.removeEventListener("change",update);custom.removeEventListener("change",update)})}catch{}return contrast}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";export function usePreferredContrast(){const contrast=ref("no-preference");if(typeof window==="undefined"||!window.matchMedia)return contrast;const more=window.matchMedia("(prefers-contrast: more)");const less=window.matchMedia("(prefers-contrast: less)");const custom=window.matchMedia("(prefers-contrast: custom)");function update(){if(more.matches)contrast.value="more";else if(less.matches)contrast.value="less";else if(custom.matches)contrast.value="custom";else contrast.value="no-preference"}update();more.addEventListener("change",update);less.addEventListener("change",update);custom.addEventListener("change",update);try{onUnmounted(()=>{more.removeEventListener("change",update);less.removeEventListener("change",update);custom.removeEventListener("change",update)})}catch{}return contrast}
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";export function usePreferredLanguages(){const languages=ref(typeof navigator<"u"?navigator.languages:[]);if(typeof window>"u")return languages;const handler=()=>{languages.value=navigator.languages};window.addEventListener("languagechange",handler,{passive:!0});try{onUnmounted(()=>{window.removeEventListener("languagechange",handler)})}catch{}return languages}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";export function usePreferredLanguages(){const languages=ref(typeof navigator!=="undefined"?navigator.languages:[]);if(typeof window==="undefined")return languages;const handler=()=>{languages.value=navigator.languages};window.addEventListener("languagechange",handler,{passive:true});try{onUnmounted(()=>{window.removeEventListener("languagechange",handler)})}catch{}return languages}
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";export function usePreferredReducedMotion(){const motion=ref("no-preference");if(typeof window>"u"||!window.matchMedia)return motion;const mq=window.matchMedia("(prefers-reduced-motion: reduce)");function update(){motion.value=mq.matches?"reduce":"no-preference"}update();mq.addEventListener("change",update);try{onUnmounted(()=>{mq.removeEventListener("change",update)})}catch{}return motion}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";export function usePreferredReducedMotion(){const motion=ref("no-preference");if(typeof window==="undefined"||!window.matchMedia)return motion;const mq=window.matchMedia("(prefers-reduced-motion: reduce)");function update(){motion.value=mq.matches?"reduce":"no-preference"}update();mq.addEventListener("change",update);try{onUnmounted(()=>{mq.removeEventListener("change",update)})}catch{}return motion}
package/dist/useQuery.js CHANGED
@@ -1 +1 @@
1
- import{ref}from"@stacksjs/stx";function stableStringify(value){if(value===null||typeof value!=="object")return JSON.stringify(value);if(Array.isArray(value))return`[${value.map(stableStringify).join(",")}]`;return`{${Object.keys(value).sort().map((k)=>`${JSON.stringify(k)}:${stableStringify(value[k])}`).join(",")}}`}function hashKey(key){return stableStringify(key)}export function createQueryClient(options={}){const entries=new Map,gcTime=options.gcTime??300000,gcTimers=new Map;function collectable(e){return e.subscribers.size===0&&e.inflight===null}function removeIfCollectable(hash){const e=entries.get(hash);if(e&&collectable(e))entries.delete(hash);gcTimers.delete(hash)}function scheduleGc(hash){const existing=gcTimers.get(hash);if(existing)clearTimeout(existing);if(!Number.isFinite(gcTime))return;if(gcTime<=0){removeIfCollectable(hash);return}const t=setTimeout(()=>removeIfCollectable(hash),gcTime);t.unref?.();gcTimers.set(hash,t)}function cancelGc(hash){const t=gcTimers.get(hash);if(t){clearTimeout(t);gcTimers.delete(hash)}}function entry(key){const hash=hashKey(key);let e=entries.get(hash);if(!e){e={key,hash,data:void 0,error:null,updatedAt:0,status:"idle",inflight:null,invalidated:!1,subscribers:new Set};entries.set(hash,e)}return e}function notify(hash){const e=entries.get(hash);if(!e)return;for(const fn of e.subscribers)fn()}function prefixMatches(prefix,candidate){if(prefix.length>candidate.length)return!1;for(let i=0;i<prefix.length;i++)if(stableStringify(prefix[i])!==stableStringify(candidate[i]))return!1;return!0}return{get(key){const hash=hashKey(key);return entries.get(hash)?.data},set(key,value){const e=entry(key),next=typeof value==="function"?value(e.data):value;e.data=next;e.updatedAt=Date.now();e.status="success";e.error=null;e.invalidated=!1;notify(e.hash)},async invalidate(matcher){const matches=Array.isArray(matcher)?(key)=>prefixMatches(matcher,key):matcher.predicate,refetches=[];for(const e of entries.values()){if(!matches(e.key))continue;e.updatedAt=0;e.invalidated=!0;for(const fn of e.subscribers){const result=fn();if(result&&typeof result.then==="function")refetches.push(result)}}await Promise.all(refetches)},clear(){for(const t of gcTimers.values())clearTimeout(t);gcTimers.clear();entries.clear()},gc(){let removed=0;for(const[hash,e]of entries)if(collectable(e)){entries.delete(hash);cancelGc(hash);removed++}return removed},_subscribe(hash,fn){const e=entries.get(hash);if(!e)return()=>{};cancelGc(hash);e.subscribers.add(fn);return()=>{e.subscribers.delete(fn);if(e.subscribers.size===0)scheduleGc(hash)}},_entry:entry,_notify:notify}}export const queryClient=createQueryClient();export function useQuery(opts){const client=opts.client??queryClient,staleTime=opts.staleTime??0,enabled=opts.enabled??!0,e=client._entry(opts.queryKey),data=ref(e.data),error=ref(e.error),isLoading=ref(e.data===void 0&&enabled),isFetching=ref(!1);function sync(){data.value=e.data;error.value=e.error;isFetching.value=e.status==="fetching";if(e.data!==void 0||e.error!==null)isLoading.value=!1}async function doFetch(force){if(!force){if(e.data!==void 0&&Date.now()-e.updatedAt<staleTime){sync();return}}if(e.inflight){try{await e.inflight}catch{}sync();return}const controller=new AbortController;e.status="fetching";isFetching.value=!0;if(e.data===void 0)isLoading.value=!0;const p=opts.queryFn({signal:controller.signal}).then((result)=>{e.data=result;e.error=null;e.updatedAt=Date.now();e.status="success";e.invalidated=!1;return result}).catch((err)=>{e.error=err instanceof Error?err:Error(String(err));e.status="error";e.invalidated=!1;throw e.error}).finally(()=>{e.inflight=null;client._notify(e.hash)});e.inflight=p;try{await p}catch{}sync()}const unsubscribeCache=client._subscribe(e.hash,()=>{if(e.invalidated&&enabled&&e.status!=="fetching")return doFetch(!0);sync();return}),target=opts.window??(typeof window<"u"?window:void 0),winListeners=[];if(target&&enabled){const onWake=()=>{if(e.status!=="fetching")doFetch(!1)};if(opts.refetchOnFocus)winListeners.push(["focus",onWake]);if(opts.refetchOnReconnect)winListeners.push(["online",onWake]);for(const[evt,fn]of winListeners)target.addEventListener(evt,fn)}function unsubscribe(){unsubscribeCache();if(target)for(const[evt,fn]of winListeners)target.removeEventListener(evt,fn)}if(enabled)doFetch(!1);else sync();return{data,error,isLoading,isFetching,refetch:()=>doFetch(!0),unsubscribe}}export function useMutation(opts){const data=ref(void 0),error=ref(null),isPending=ref(!1);async function run(vars){isPending.value=!0;error.value=null;let ctx;try{if(opts.onMutate)ctx=await opts.onMutate(vars);const result=await opts.mutationFn(vars);data.value=result;await opts.onSuccess?.(result,vars,ctx);await opts.onSettled?.(result,null,vars,ctx);return result}catch(err){const e=err instanceof Error?err:Error(String(err));error.value=e;await opts.onError?.(e,vars,ctx);await opts.onSettled?.(void 0,e,vars,ctx);throw e}finally{isPending.value=!1}}return{data,error,isPending,mutate(vars){run(vars).catch(()=>{})},mutateAsync:run,reset(){data.value=void 0;error.value=null;isPending.value=!1}}}
1
+ import{ref}from"@stacksjs/stx";function stableStringify(value){if(value===null||typeof value!=="object")return JSON.stringify(value);if(Array.isArray(value))return`[${value.map(stableStringify).join(",")}]`;const keys=Object.keys(value).sort();return`{${keys.map((k)=>`${JSON.stringify(k)}:${stableStringify(value[k])}`).join(",")}}`}function hashKey(key){return stableStringify(key)}export function createQueryClient(options={}){const entries=new Map;const gcTime=options.gcTime??5*60*1000;const gcTimers=new Map;function collectable(e){return e.subscribers.size===0&&e.inflight===null}function removeIfCollectable(hash){const e=entries.get(hash);if(e&&collectable(e))entries.delete(hash);gcTimers.delete(hash)}function scheduleGc(hash){const existing=gcTimers.get(hash);if(existing)clearTimeout(existing);if(!Number.isFinite(gcTime))return;if(gcTime<=0){removeIfCollectable(hash);return}const t=setTimeout(()=>removeIfCollectable(hash),gcTime);t.unref?.();gcTimers.set(hash,t)}function cancelGc(hash){const t=gcTimers.get(hash);if(t){clearTimeout(t);gcTimers.delete(hash)}}function entry(key){const hash=hashKey(key);let e=entries.get(hash);if(!e){e={key,hash,data:undefined,error:null,updatedAt:0,status:"idle",inflight:null,invalidated:false,subscribers:new Set};entries.set(hash,e)}return e}function notify(hash){const e=entries.get(hash);if(!e)return;for(const fn of e.subscribers)fn()}function prefixMatches(prefix,candidate){if(prefix.length>candidate.length)return false;for(let i=0;i<prefix.length;i++){if(stableStringify(prefix[i])!==stableStringify(candidate[i]))return false}return true}return{get(key){const hash=hashKey(key);return entries.get(hash)?.data},set(key,value){const e=entry(key);const next=typeof value==="function"?value(e.data):value;e.data=next;e.updatedAt=Date.now();e.status="success";e.error=null;e.invalidated=false;notify(e.hash)},async invalidate(matcher){const matches=Array.isArray(matcher)?(key)=>prefixMatches(matcher,key):matcher.predicate;const refetches=[];for(const e of entries.values()){if(!matches(e.key))continue;e.updatedAt=0;e.invalidated=true;for(const fn of e.subscribers){const result=fn();if(result&&typeof result.then==="function"){refetches.push(result)}}}await Promise.all(refetches)},clear(){for(const t of gcTimers.values())clearTimeout(t);gcTimers.clear();entries.clear()},gc(){let removed=0;for(const[hash,e]of entries){if(collectable(e)){entries.delete(hash);cancelGc(hash);removed++}}return removed},_subscribe(hash,fn){const e=entries.get(hash);if(!e)return()=>{};cancelGc(hash);e.subscribers.add(fn);return()=>{e.subscribers.delete(fn);if(e.subscribers.size===0)scheduleGc(hash)}},_entry:entry,_notify:notify}}export const queryClient=createQueryClient();export function useQuery(opts){const client=opts.client??queryClient;const staleTime=opts.staleTime??0;const enabled=opts.enabled??true;const e=client._entry(opts.queryKey);const data=ref(e.data);const error=ref(e.error);const isLoading=ref(e.data===undefined&&enabled);const isFetching=ref(false);function sync(){data.value=e.data;error.value=e.error;isFetching.value=e.status==="fetching";if(e.data!==undefined||e.error!==null){isLoading.value=false}}async function doFetch(force){if(!force){const fresh=e.data!==undefined&&Date.now()-e.updatedAt<staleTime;if(fresh){sync();return}}if(e.inflight){try{await e.inflight}catch{}sync();return}const controller=new AbortController;e.status="fetching";isFetching.value=true;if(e.data===undefined)isLoading.value=true;const p=opts.queryFn({signal:controller.signal}).then((result)=>{e.data=result;e.error=null;e.updatedAt=Date.now();e.status="success";e.invalidated=false;return result}).catch((err)=>{e.error=err instanceof Error?err:new Error(String(err));e.status="error";e.invalidated=false;throw e.error}).finally(()=>{e.inflight=null;client._notify(e.hash)});e.inflight=p;try{await p}catch{}sync()}const unsubscribeCache=client._subscribe(e.hash,()=>{if(e.invalidated&&enabled&&e.status!=="fetching"){return doFetch(true)}sync();return});const target=opts.window??(typeof window!=="undefined"?window:undefined);const winListeners=[];if(target&&enabled){const onWake=()=>{if(e.status!=="fetching")doFetch(false)};if(opts.refetchOnFocus)winListeners.push(["focus",onWake]);if(opts.refetchOnReconnect)winListeners.push(["online",onWake]);for(const[evt,fn]of winListeners)target.addEventListener(evt,fn)}function unsubscribe(){unsubscribeCache();if(target){for(const[evt,fn]of winListeners)target.removeEventListener(evt,fn)}}if(enabled)doFetch(false);else sync();return{data,error,isLoading,isFetching,refetch:()=>doFetch(true),unsubscribe}}export function useMutation(opts){const data=ref(undefined);const error=ref(null);const isPending=ref(false);async function run(vars){isPending.value=true;error.value=null;let ctx;try{if(opts.onMutate)ctx=await opts.onMutate(vars);const result=await opts.mutationFn(vars);data.value=result;await opts.onSuccess?.(result,vars,ctx);await opts.onSettled?.(result,null,vars,ctx);return result}catch(err){const e=err instanceof Error?err:new Error(String(err));error.value=e;await opts.onError?.(e,vars,ctx);await opts.onSettled?.(undefined,e,vars,ctx);throw e}finally{isPending.value=false}}return{data,error,isPending,mutate(vars){run(vars).catch(()=>{})},mutateAsync:run,reset(){data.value=undefined;error.value=null;isPending.value=false}}}
package/dist/useRafFn.js CHANGED
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";export function useRafFn(fn,options={}){const{immediate=!0}=options,isActive=ref(!1);let rafId=null,previousTimestamp=0;function loop(timestamp){if(!isActive.value)return;const delta=previousTimestamp?timestamp-previousTimestamp:0;previousTimestamp=timestamp;fn({delta,timestamp});rafId=requestAnimationFrame(loop)}function resume(){if(isActive.value)return;if(typeof requestAnimationFrame>"u")return;isActive.value=!0;previousTimestamp=0;rafId=requestAnimationFrame(loop)}function pause(){if(!isActive.value)return;isActive.value=!1;if(rafId!==null&&typeof cancelAnimationFrame<"u"){cancelAnimationFrame(rafId);rafId=null}}if(immediate)resume();try{onUnmounted(pause)}catch{}return{pause,resume,isActive}}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";export function useRafFn(fn,options={}){const{immediate=true}=options;const isActive=ref(false);let rafId=null;let previousTimestamp=0;function loop(timestamp){if(!isActive.value)return;const delta=previousTimestamp?timestamp-previousTimestamp:0;previousTimestamp=timestamp;fn({delta,timestamp});rafId=requestAnimationFrame(loop)}function resume(){if(isActive.value)return;if(typeof requestAnimationFrame==="undefined")return;isActive.value=true;previousTimestamp=0;rafId=requestAnimationFrame(loop)}function pause(){if(!isActive.value)return;isActive.value=false;if(rafId!==null&&typeof cancelAnimationFrame!=="undefined"){cancelAnimationFrame(rafId);rafId=null}}if(immediate){resume()}try{onUnmounted(pause)}catch{}return{pause,resume,isActive}}
@@ -1 +1 @@
1
- import{computed,ref,watch}from"@stacksjs/stx";function cloneValue(val,shouldClone){if(!shouldClone)return val;if(typeof structuredClone==="function")return structuredClone(val);return JSON.parse(JSON.stringify(val))}export function useRefHistory(source,options={}){const{capacity=1/0,deep=!1,clone=!1}=options,undoStack=ref([{snapshot:cloneValue(source.value,clone),timestamp:Date.now()}]),redoStack=ref([]);let isUndoRedoing=!1;const canUndo=computed(()=>undoStack.value.length>1),canRedo=computed(()=>redoStack.value.length>0),last=computed(()=>{return undoStack.value[undoStack.value.length-1]});function commit(){const record={snapshot:cloneValue(source.value,clone),timestamp:Date.now()};undoStack.value=[...undoStack.value,record];if(capacity!==1/0&&undoStack.value.length>capacity)undoStack.value=undoStack.value.slice(undoStack.value.length-capacity);redoStack.value=[]}function undo(){if(undoStack.value.length<=1)return;isUndoRedoing=!0;const current=undoStack.value[undoStack.value.length-1],newUndoStack=undoStack.value.slice(0,-1);undoStack.value=newUndoStack;if(current)redoStack.value=[...redoStack.value,current];const previous=newUndoStack[newUndoStack.length-1];if(previous)source.value=cloneValue(previous.snapshot,clone);isUndoRedoing=!1}function redo(){if(redoStack.value.length===0)return;isUndoRedoing=!0;const next=redoStack.value[redoStack.value.length-1];redoStack.value=redoStack.value.slice(0,-1);if(next){undoStack.value=[...undoStack.value,next];source.value=cloneValue(next.snapshot,clone)}isUndoRedoing=!1}function clear(){undoStack.value=[{snapshot:cloneValue(source.value,clone),timestamp:Date.now()}];redoStack.value=[]}watch(source,()=>{if(!isUndoRedoing)commit()},{deep});return{history:undoStack,commit,undo,redo,canUndo,canRedo,clear,last}}
1
+ import{computed,ref,watch}from"@stacksjs/stx";function cloneValue(val,shouldClone){if(!shouldClone)return val;if(typeof structuredClone==="function"){return structuredClone(val)}return JSON.parse(JSON.stringify(val))}export function useRefHistory(source,options={}){const{capacity=1/0,deep=false,clone=false}=options;const undoStack=ref([{snapshot:cloneValue(source.value,clone),timestamp:Date.now()}]);const redoStack=ref([]);let isUndoRedoing=false;const canUndo=computed(()=>undoStack.value.length>1);const canRedo=computed(()=>redoStack.value.length>0);const last=computed(()=>{return undoStack.value[undoStack.value.length-1]});function commit(){const record={snapshot:cloneValue(source.value,clone),timestamp:Date.now()};undoStack.value=[...undoStack.value,record];if(capacity!==1/0&&undoStack.value.length>capacity){undoStack.value=undoStack.value.slice(undoStack.value.length-capacity)}redoStack.value=[]}function undo(){if(undoStack.value.length<=1)return;isUndoRedoing=true;const current=undoStack.value[undoStack.value.length-1];const newUndoStack=undoStack.value.slice(0,-1);undoStack.value=newUndoStack;if(current)redoStack.value=[...redoStack.value,current];const previous=newUndoStack[newUndoStack.length-1];if(previous)source.value=cloneValue(previous.snapshot,clone);isUndoRedoing=false}function redo(){if(redoStack.value.length===0)return;isUndoRedoing=true;const next=redoStack.value[redoStack.value.length-1];redoStack.value=redoStack.value.slice(0,-1);if(next){undoStack.value=[...undoStack.value,next];source.value=cloneValue(next.snapshot,clone)}isUndoRedoing=false}function clear(){undoStack.value=[{snapshot:cloneValue(source.value,clone),timestamp:Date.now()}];redoStack.value=[]}watch(source,()=>{if(!isUndoRedoing){commit()}},{deep});return{history:undoStack,commit,undo,redo,canUndo,canRedo,clear,last}}
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";import{unref,noop}from"./_shared";export function useResizeObserver(target,callback,options){const isSupported=ref(typeof window<"u"&&"ResizeObserver"in window);let cleanup=noop;(()=>{cleanup();if(!isSupported.value)return;const el=unref(target);if(!el)return;const observer=new ResizeObserver(callback);observer.observe(el,options);cleanup=()=>{observer.disconnect();cleanup=noop}})();const stop=()=>{cleanup()};try{onUnmounted(stop)}catch{}return{isSupported,stop}}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";import{unref,noop}from"./_shared";export function useResizeObserver(target,callback,options){const isSupported=ref(typeof window!=="undefined"&&"ResizeObserver"in window);let cleanup=noop;const observe=()=>{cleanup();if(!isSupported.value)return;const el=unref(target);if(!el)return;const observer=new ResizeObserver(callback);observer.observe(el,options);cleanup=()=>{observer.disconnect();cleanup=noop}};observe();const stop=()=>{cleanup()};try{onUnmounted(stop)}catch{}return{isSupported,stop}}
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";export function useScreenOrientation(){const isSupported=ref(typeof screen<"u"&&"orientation"in screen),orientation=ref(void 0),angle=ref(0);if(isSupported.value){orientation.value=screen.orientation.type;angle.value=screen.orientation.angle;const handler=()=>{orientation.value=screen.orientation.type;angle.value=screen.orientation.angle};screen.orientation.addEventListener("change",handler);try{onUnmounted(()=>{screen.orientation.removeEventListener("change",handler)})}catch{}}async function lockOrientation(type){if(isSupported.value)await screen.orientation.lock(type)}function unlockOrientation(){if(isSupported.value)screen.orientation.unlock()}return{isSupported,orientation,angle,lockOrientation,unlockOrientation}}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";export function useScreenOrientation(){const isSupported=ref(typeof screen!=="undefined"&&"orientation"in screen);const orientation=ref(undefined);const angle=ref(0);if(isSupported.value){orientation.value=screen.orientation.type;angle.value=screen.orientation.angle;const handler=()=>{orientation.value=screen.orientation.type;angle.value=screen.orientation.angle};screen.orientation.addEventListener("change",handler);try{onUnmounted(()=>{screen.orientation.removeEventListener("change",handler)})}catch{}}async function lockOrientation(type){if(isSupported.value){const orient=screen.orientation;await orient.lock(type)}}function unlockOrientation(){if(isSupported.value)screen.orientation.unlock()}return{isSupported,orientation,angle,lockOrientation,unlockOrientation}}
@@ -1 +1 @@
1
- import{ref}from"@stacksjs/stx";export function useScreenSafeArea(){const top=ref("0px"),right=ref("0px"),bottom=ref("0px"),left=ref("0px");function update(){if(typeof document>"u"||typeof getComputedStyle>"u")return;const div=document.createElement("div");div.style.position="fixed";div.style.top="env(safe-area-inset-top, 0px)";div.style.right="env(safe-area-inset-right, 0px)";div.style.bottom="env(safe-area-inset-bottom, 0px)";div.style.left="env(safe-area-inset-left, 0px)";div.style.pointerEvents="none";div.style.visibility="hidden";document.body.appendChild(div);const style=getComputedStyle(div);top.value=style.top;right.value=style.right;bottom.value=style.bottom;left.value=style.left;document.body.removeChild(div)}update();return{top,right,bottom,left,update}}
1
+ import{ref}from"@stacksjs/stx";export function useScreenSafeArea(){const top=ref("0px");const right=ref("0px");const bottom=ref("0px");const left=ref("0px");function update(){if(typeof document==="undefined"||typeof getComputedStyle==="undefined")return;const div=document.createElement("div");div.style.position="fixed";div.style.top="env(safe-area-inset-top, 0px)";div.style.right="env(safe-area-inset-right, 0px)";div.style.bottom="env(safe-area-inset-bottom, 0px)";div.style.left="env(safe-area-inset-left, 0px)";div.style.pointerEvents="none";div.style.visibility="hidden";document.body.appendChild(div);const style=getComputedStyle(div);top.value=style.top;right.value=style.right;bottom.value=style.bottom;left.value=style.left;document.body.removeChild(div)}update();return{top,right,bottom,left,update}}
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";export function useScriptTag(src,onLoaded,options={}){const{immediate=!0,type="text/javascript",manual=!1,attrs={}}=options,scriptTag=ref(null);function load(){return new Promise((resolve,reject)=>{if(typeof document>"u"){reject(Error("Document is not available"));return}const el=document.createElement("script");el.type=type;el.src=src;if(options.async)el.async=!0;if(options.defer)el.defer=!0;if(options.crossOrigin)el.crossOrigin=options.crossOrigin;if(options.referrerPolicy)el.referrerPolicy=options.referrerPolicy;for(const[key,value]of Object.entries(attrs))el.setAttribute(key,value);el.addEventListener("load",()=>{scriptTag.value=el;onLoaded?.(el);resolve(el)});el.addEventListener("error",(event)=>{reject(event)});document.head.appendChild(el)})}function unload(){if(scriptTag.value){scriptTag.value.remove();scriptTag.value=null}}if(immediate)load();if(!manual)try{onUnmounted(()=>unload())}catch{}return{scriptTag,load,unload}}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";export function useScriptTag(src,onLoaded,options={}){const{immediate=true,type="text/javascript",manual=false,attrs={}}=options;const scriptTag=ref(null);function load(){return new Promise((resolve,reject)=>{if(typeof document==="undefined"){reject(new Error("Document is not available"));return}const el=document.createElement("script");el.type=type;el.src=src;if(options.async)el.async=true;if(options.defer)el.defer=true;if(options.crossOrigin)el.crossOrigin=options.crossOrigin;if(options.referrerPolicy)el.referrerPolicy=options.referrerPolicy;for(const[key,value]of Object.entries(attrs))el.setAttribute(key,value);el.addEventListener("load",()=>{scriptTag.value=el;onLoaded?.(el);resolve(el)});el.addEventListener("error",(event)=>{reject(event)});document.head.appendChild(el)})}function unload(){if(scriptTag.value){scriptTag.value.remove();scriptTag.value=null}}if(immediate)load();if(!manual){try{onUnmounted(()=>unload())}catch{}}return{scriptTag,load,unload}}
package/dist/useScroll.js CHANGED
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";import{unref}from"./_shared";export function useScroll(target,options){const{throttle=0,offset={}}=options??{},offsetTop=offset.top??0,offsetBottom=offset.bottom??0,offsetLeft=offset.left??0,offsetRight=offset.right??0,x=ref(0),y=ref(0),isScrolling=ref(!1),arrivedTop=ref(!0),arrivedBottom=ref(!1),arrivedLeft=ref(!0),arrivedRight=ref(!1),dirTop=ref(!1),dirBottom=ref(!1),dirLeft=ref(!1),dirRight=ref(!1);let scrollingTimer,lastX=0,lastY=0,throttleTimer,isThrottled=!1;function getScrollPosition(el){if(typeof window<"u"&&el===window||"innerHeight"in el&&"scrollX"in el){const win=el,doc=typeof document<"u"?document:void 0;return{scrollLeft:win.scrollX??win.pageXOffset??0,scrollTop:win.scrollY??win.pageYOffset??0,scrollHeight:doc?.documentElement?.scrollHeight??0,scrollWidth:doc?.documentElement?.scrollWidth??0,clientHeight:win.innerHeight,clientWidth:win.innerWidth}}if(typeof document<"u"&&el===document||"documentElement"in el){const docEl=el.documentElement;return{scrollLeft:docEl.scrollLeft,scrollTop:docEl.scrollTop,scrollHeight:docEl.scrollHeight,scrollWidth:docEl.scrollWidth,clientHeight:docEl.clientHeight,clientWidth:docEl.clientWidth}}const htmlEl=el;return{scrollLeft:htmlEl.scrollLeft,scrollTop:htmlEl.scrollTop,scrollHeight:htmlEl.scrollHeight,scrollWidth:htmlEl.scrollWidth,clientHeight:htmlEl.clientHeight,clientWidth:htmlEl.clientWidth}}function update(){const el=target?unref(target):typeof window<"u"?window:null;if(!el)return;const pos=getScrollPosition(el);dirTop.value=pos.scrollTop<lastY;dirBottom.value=pos.scrollTop>lastY;dirLeft.value=pos.scrollLeft<lastX;dirRight.value=pos.scrollLeft>lastX;lastX=pos.scrollLeft;lastY=pos.scrollTop;x.value=pos.scrollLeft;y.value=pos.scrollTop;arrivedTop.value=pos.scrollTop<=offsetTop;arrivedLeft.value=pos.scrollLeft<=offsetLeft;arrivedBottom.value=pos.scrollTop+pos.clientHeight>=pos.scrollHeight-offsetBottom;arrivedRight.value=pos.scrollLeft+pos.clientWidth>=pos.scrollWidth-offsetRight;isScrolling.value=!0;if(scrollingTimer)clearTimeout(scrollingTimer);scrollingTimer=setTimeout(()=>{isScrolling.value=!1},150)}function onScroll(){if(throttle>0){if(!isThrottled){update();isThrottled=!0;throttleTimer=setTimeout(()=>{isThrottled=!1},throttle)}}else update()}if(typeof window<"u"){const el=target?unref(target):window;if(el){const pos=getScrollPosition(el);x.value=pos.scrollLeft;y.value=pos.scrollTop;lastX=pos.scrollLeft;lastY=pos.scrollTop;arrivedTop.value=pos.scrollTop<=offsetTop;arrivedLeft.value=pos.scrollLeft<=offsetLeft;arrivedBottom.value=pos.scrollTop+pos.clientHeight>=pos.scrollHeight-offsetBottom;arrivedRight.value=pos.scrollLeft+pos.clientWidth>=pos.scrollWidth-offsetRight;el.addEventListener("scroll",onScroll,{passive:!0});try{onUnmounted(()=>{el.removeEventListener("scroll",onScroll);if(scrollingTimer)clearTimeout(scrollingTimer);if(throttleTimer)clearTimeout(throttleTimer)})}catch{}}}return{x,y,isScrolling,arrivedState:{top:arrivedTop,bottom:arrivedBottom,left:arrivedLeft,right:arrivedRight},directions:{top:dirTop,bottom:dirBottom,left:dirLeft,right:dirRight}}}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";import{unref}from"./_shared";export function useScroll(target,options){const{throttle=0,offset={}}=options??{};const offsetTop=offset.top??0;const offsetBottom=offset.bottom??0;const offsetLeft=offset.left??0;const offsetRight=offset.right??0;const x=ref(0);const y=ref(0);const isScrolling=ref(false);const arrivedTop=ref(true);const arrivedBottom=ref(false);const arrivedLeft=ref(true);const arrivedRight=ref(false);const dirTop=ref(false);const dirBottom=ref(false);const dirLeft=ref(false);const dirRight=ref(false);let scrollingTimer;let lastX=0;let lastY=0;let throttleTimer;let isThrottled=false;function getScrollPosition(el){if(typeof window!=="undefined"&&el===window||"innerHeight"in el&&"scrollX"in el){const win=el;const doc=typeof document!=="undefined"?document:undefined;return{scrollLeft:win.scrollX??win.pageXOffset??0,scrollTop:win.scrollY??win.pageYOffset??0,scrollHeight:doc?.documentElement?.scrollHeight??0,scrollWidth:doc?.documentElement?.scrollWidth??0,clientHeight:win.innerHeight,clientWidth:win.innerWidth}}if(typeof document!=="undefined"&&el===document||"documentElement"in el){const docEl=el.documentElement;return{scrollLeft:docEl.scrollLeft,scrollTop:docEl.scrollTop,scrollHeight:docEl.scrollHeight,scrollWidth:docEl.scrollWidth,clientHeight:docEl.clientHeight,clientWidth:docEl.clientWidth}}const htmlEl=el;return{scrollLeft:htmlEl.scrollLeft,scrollTop:htmlEl.scrollTop,scrollHeight:htmlEl.scrollHeight,scrollWidth:htmlEl.scrollWidth,clientHeight:htmlEl.clientHeight,clientWidth:htmlEl.clientWidth}}function update(){const el=target?unref(target):typeof window!=="undefined"?window:null;if(!el)return;const pos=getScrollPosition(el);dirTop.value=pos.scrollTop<lastY;dirBottom.value=pos.scrollTop>lastY;dirLeft.value=pos.scrollLeft<lastX;dirRight.value=pos.scrollLeft>lastX;lastX=pos.scrollLeft;lastY=pos.scrollTop;x.value=pos.scrollLeft;y.value=pos.scrollTop;arrivedTop.value=pos.scrollTop<=offsetTop;arrivedLeft.value=pos.scrollLeft<=offsetLeft;arrivedBottom.value=pos.scrollTop+pos.clientHeight>=pos.scrollHeight-offsetBottom;arrivedRight.value=pos.scrollLeft+pos.clientWidth>=pos.scrollWidth-offsetRight;isScrolling.value=true;if(scrollingTimer)clearTimeout(scrollingTimer);scrollingTimer=setTimeout(()=>{isScrolling.value=false},150)}function onScroll(){if(throttle>0){if(!isThrottled){update();isThrottled=true;throttleTimer=setTimeout(()=>{isThrottled=false},throttle)}}else{update()}}if(typeof window!=="undefined"){const el=target?unref(target):window;if(el){const pos=getScrollPosition(el);x.value=pos.scrollLeft;y.value=pos.scrollTop;lastX=pos.scrollLeft;lastY=pos.scrollTop;arrivedTop.value=pos.scrollTop<=offsetTop;arrivedLeft.value=pos.scrollLeft<=offsetLeft;arrivedBottom.value=pos.scrollTop+pos.clientHeight>=pos.scrollHeight-offsetBottom;arrivedRight.value=pos.scrollLeft+pos.clientWidth>=pos.scrollWidth-offsetRight;el.addEventListener("scroll",onScroll,{passive:true});try{onUnmounted(()=>{el.removeEventListener("scroll",onScroll);if(scrollingTimer)clearTimeout(scrollingTimer);if(throttleTimer)clearTimeout(throttleTimer)})}catch{}}}return{x,y,isScrolling,arrivedState:{top:arrivedTop,bottom:arrivedBottom,left:arrivedLeft,right:arrivedRight},directions:{top:dirTop,bottom:dirBottom,left:dirLeft,right:dirRight}}}
@@ -1 +1 @@
1
- import{onUnmounted,ref,watch}from"@stacksjs/stx";import{unref}from"./_shared";export function useScrollLock(element){const isLocked=ref(!1);let originalOverflow="";function getElement(){if(element)return unref(element);if(typeof document<"u")return document.body;return null}function lock(){const el=getElement();if(!el)return;originalOverflow=el.style.overflow;el.style.overflow="hidden"}function unlock(){const el=getElement();if(!el)return;el.style.overflow=originalOverflow}watch(isLocked,(val)=>{if(val)lock();else unlock()});try{onUnmounted(()=>{if(isLocked.value)unlock()})}catch{}return isLocked}
1
+ import{onUnmounted,ref,watch}from"@stacksjs/stx";import{unref}from"./_shared";export function useScrollLock(element){const isLocked=ref(false);let originalOverflow="";function getElement(){if(element){return unref(element)}if(typeof document!=="undefined"){return document.body}return null}function lock(){const el=getElement();if(!el)return;originalOverflow=el.style.overflow;el.style.overflow="hidden"}function unlock(){const el=getElement();if(!el)return;el.style.overflow=originalOverflow}watch(isLocked,(val)=>{if(val){lock()}else{unlock()}});try{onUnmounted(()=>{if(isLocked.value){unlock()}})}catch{}return isLocked}
@@ -1 +1 @@
1
- import{useStorage}from"./useStorage";export function useSessionStorage(key,defaultValue,options){return useStorage(key,defaultValue,typeof sessionStorage<"u"?sessionStorage:void 0,options)}
1
+ import{useStorage}from"./useStorage";export function useSessionStorage(key,defaultValue,options){const storage=typeof sessionStorage!=="undefined"?sessionStorage:undefined;return useStorage(key,defaultValue,storage,options)}
package/dist/useShare.js CHANGED
@@ -1 +1 @@
1
- import{ref}from"@stacksjs/stx";export function useShare(options={}){const isSupported=ref(typeof navigator<"u"&&"share"in navigator);async function share(overrideOptions){if(!isSupported.value)return;const shareData={...options,...overrideOptions};await navigator.share(shareData)}return{share,isSupported}}
1
+ import{ref}from"@stacksjs/stx";export function useShare(options={}){const isSupported=ref(typeof navigator!=="undefined"&&"share"in navigator);async function share(overrideOptions){if(!isSupported.value)return;const shareData={...options,...overrideOptions};await navigator.share(shareData)}return{share,isSupported}}
package/dist/useSorted.js CHANGED
@@ -1 +1 @@
1
- import{computed}from"@stacksjs/stx";import{unref}from"./_shared";export function useSorted(source,compareFn){return computed(()=>{const arr=[...unref(source)];if(compareFn)return arr.sort(compareFn);return arr.sort()})}
1
+ import{computed}from"@stacksjs/stx";import{unref}from"./_shared";export function useSorted(source,compareFn){return computed(()=>{const arr=[...unref(source)];if(compareFn){return arr.sort(compareFn)}return arr.sort()})}
@@ -1 +1 @@
1
- import{computed,ref}from"@stacksjs/stx";export function useStepper(steps,initialStep){const stepsRef=ref([...steps]),initialIndex=initialStep!==void 0?steps.indexOf(initialStep):0,index=ref(initialIndex>=0?initialIndex:0),current=computed(()=>stepsRef.value[index.value]),isFirst=computed(()=>index.value===0),isLast=computed(()=>index.value===stepsRef.value.length-1);function next(){if(index.value<stepsRef.value.length-1)index.value++}function previous(){if(index.value>0)index.value--}function goTo(step){const idx=stepsRef.value.indexOf(step);if(idx>=0)index.value=idx}function goToIndex(idx){if(idx>=0&&idx<stepsRef.value.length)index.value=idx}function isBefore(step){const stepIndex=stepsRef.value.indexOf(step);return stepIndex>=0&&index.value<stepIndex}function isAfter(step){const stepIndex=stepsRef.value.indexOf(step);return stepIndex>=0&&index.value>stepIndex}function isCurrent(step){return stepsRef.value[index.value]===step}return{steps:stepsRef,current,index,isFirst,isLast,next,previous,goTo,goToIndex,isBefore,isAfter,isCurrent}}
1
+ import{computed,ref}from"@stacksjs/stx";export function useStepper(steps,initialStep){const stepsRef=ref([...steps]);const initialIndex=initialStep!==undefined?steps.indexOf(initialStep):0;const index=ref(initialIndex>=0?initialIndex:0);const current=computed(()=>stepsRef.value[index.value]);const isFirst=computed(()=>index.value===0);const isLast=computed(()=>index.value===stepsRef.value.length-1);function next(){if(index.value<stepsRef.value.length-1){index.value++}}function previous(){if(index.value>0){index.value--}}function goTo(step){const idx=stepsRef.value.indexOf(step);if(idx>=0){index.value=idx}}function goToIndex(idx){if(idx>=0&&idx<stepsRef.value.length){index.value=idx}}function isBefore(step){const stepIndex=stepsRef.value.indexOf(step);return stepIndex>=0&&index.value<stepIndex}function isAfter(step){const stepIndex=stepsRef.value.indexOf(step);return stepIndex>=0&&index.value>stepIndex}function isCurrent(step){return stepsRef.value[index.value]===step}return{steps:stepsRef,current,index,isFirst,isLast,next,previous,goTo,goToIndex,isBefore,isAfter,isCurrent}}
@@ -1 +1 @@
1
- import{onUnmounted,ref,watch}from"@stacksjs/stx";export function useStorage(key,defaultValue,storage,options){const store=storage??(typeof localStorage<"u"?localStorage:void 0),serializer=options?.serializer??{read:(raw)=>{try{return JSON.parse(raw)}catch{return raw}},write:(value)=>JSON.stringify(value)};let initialValue=defaultValue;if(store)try{const raw=store.getItem(key);if(raw!==null)initialValue=serializer.read(raw)}catch{}const data=ref(initialValue);watch(data,(val)=>{if(!store)return;try{if(val===null||val===void 0)store.removeItem(key);else store.setItem(key,serializer.write(val))}catch(err){const name=err?.name??"",msg=err?.message??String(err);if(name==="QuotaExceededError"||/quota/i.test(msg))console.warn(`[useStorage] ${key}: storage quota exceeded - value not persisted.`);else console.warn(`[useStorage] ${key}: failed to persist value - ${msg}`)}});if(typeof window<"u"){const onStorageChange=(e)=>{if(e.key!==key||e.storageArea!==store)return;if(e.newValue===null)data.value=defaultValue;else try{data.value=serializer.read(e.newValue)}catch{data.value=defaultValue}};window.addEventListener("storage",onStorageChange);onUnmounted(()=>window.removeEventListener("storage",onStorageChange))}return data}
1
+ import{onUnmounted,ref,watch}from"@stacksjs/stx";export function useStorage(key,defaultValue,storage,options){const store=storage??(typeof localStorage!=="undefined"?localStorage:undefined);const serializer=options?.serializer??{read:(raw)=>{try{return JSON.parse(raw)}catch{return raw}},write:(value)=>JSON.stringify(value)};let initialValue=defaultValue;if(store){try{const raw=store.getItem(key);if(raw!==null){initialValue=serializer.read(raw)}}catch{}}const data=ref(initialValue);watch(data,(val)=>{if(!store)return;try{if(val===null||val===undefined){store.removeItem(key)}else{store.setItem(key,serializer.write(val))}}catch(err){const name=err?.name??"";const msg=err?.message??String(err);if(name==="QuotaExceededError"||/quota/i.test(msg)){console.warn(`[useStorage] ${key}: storage quota exceeded - value not persisted.`)}else{console.warn(`[useStorage] ${key}: failed to persist value - ${msg}`)}}});if(typeof window!=="undefined"){const onStorageChange=(e)=>{if(e.key!==key||e.storageArea!==store)return;if(e.newValue===null){data.value=defaultValue}else{try{data.value=serializer.read(e.newValue)}catch{data.value=defaultValue}}};window.addEventListener("storage",onStorageChange);onUnmounted(()=>window.removeEventListener("storage",onStorageChange))}return data}
@@ -1 +1 @@
1
- import{onUnmounted,ref,watch}from"@stacksjs/stx";export function useStyleTag(initialCss,options={}){const{immediate=!0,id=`style-${Math.random().toString(36).slice(2,9)}`,media}=options,css=ref(initialCss),isLoaded=ref(!1);let styleEl=null;function load(){if(typeof document>"u")return;if(styleEl)return;styleEl=document.createElement("style");styleEl.id=id;if(media)styleEl.media=media;styleEl.textContent=css.value;document.head.appendChild(styleEl);isLoaded.value=!0}function unload(){if(styleEl){styleEl.remove();styleEl=null;isLoaded.value=!1}}watch(css,(val)=>{if(styleEl)styleEl.textContent=val});if(immediate)load();try{onUnmounted(()=>unload())}catch{}return{id,css,load,unload,isLoaded}}
1
+ import{onUnmounted,ref,watch}from"@stacksjs/stx";export function useStyleTag(initialCss,options={}){const{immediate=true,id=`style-${Math.random().toString(36).slice(2,9)}`,media}=options;const css=ref(initialCss);const isLoaded=ref(false);let styleEl=null;function load(){if(typeof document==="undefined")return;if(styleEl)return;styleEl=document.createElement("style");styleEl.id=id;if(media)styleEl.media=media;styleEl.textContent=css.value;document.head.appendChild(styleEl);isLoaded.value=true}function unload(){if(styleEl){styleEl.remove();styleEl=null;isLoaded.value=false}}watch(css,(val)=>{if(styleEl)styleEl.textContent=val});if(immediate)load();try{onUnmounted(()=>unload())}catch{}return{id,css,load,unload,isLoaded}}
@@ -1 +1 @@
1
- import{ref}from"@stacksjs/stx";export function useSupported(callback){const isSupported=ref(!1);try{isSupported.value=callback()}catch{isSupported.value=!1}return isSupported}
1
+ import{ref}from"@stacksjs/stx";export function useSupported(callback){const isSupported=ref(false);try{isSupported.value=callback()}catch{isSupported.value=false}return isSupported}
package/dist/useSwipe.js CHANGED
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";import{unref}from"./_shared";export function useSwipe(target,options={}){const{threshold=50,onSwipe,onSwipeStart,onSwipeEnd,passive=!0}=options,isSwiping=ref(!1),direction=ref("none"),lengthX=ref(0),lengthY=ref(0);let startX=0,startY=0;if(typeof window>"u")return{isSwiping,direction,lengthX,lengthY};const el=unref(target)??window,onTouchStart=(e)=>{const touch=e.touches[0];if(!touch)return;startX=touch.clientX;startY=touch.clientY;isSwiping.value=!0;direction.value="none";lengthX.value=0;lengthY.value=0;onSwipeStart?.(e)},onTouchMove=(e)=>{if(!isSwiping.value)return;const touch=e.touches[0];if(!touch)return;lengthX.value=touch.clientX-startX;lengthY.value=touch.clientY-startY;const absX=Math.abs(lengthX.value),absY=Math.abs(lengthY.value);if(absX>absY)direction.value=lengthX.value>0?"right":"left";else if(absY>absX)direction.value=lengthY.value>0?"down":"up"},onTouchEnd=(e)=>{if(!isSwiping.value)return;isSwiping.value=!1;const absX=Math.abs(lengthX.value),absY=Math.abs(lengthY.value);if(Math.max(absX,absY)>=threshold){onSwipe?.(direction.value);onSwipeEnd?.(e,direction.value)}else{direction.value="none";onSwipeEnd?.(e,"none")}};el.addEventListener("touchstart",onTouchStart,{passive});el.addEventListener("touchmove",onTouchMove,{passive});el.addEventListener("touchend",onTouchEnd,{passive});el.addEventListener("touchcancel",onTouchEnd,{passive});try{onUnmounted(()=>{el.removeEventListener("touchstart",onTouchStart);el.removeEventListener("touchmove",onTouchMove);el.removeEventListener("touchend",onTouchEnd);el.removeEventListener("touchcancel",onTouchEnd)})}catch{}return{isSwiping,direction,lengthX,lengthY}}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";import{unref}from"./_shared";export function useSwipe(target,options={}){const{threshold=50,onSwipe,onSwipeStart,onSwipeEnd,passive=true}=options;const isSwiping=ref(false);const direction=ref("none");const lengthX=ref(0);const lengthY=ref(0);let startX=0;let startY=0;if(typeof window==="undefined")return{isSwiping,direction,lengthX,lengthY};const el=unref(target)??window;const onTouchStart=(e)=>{const touch=e.touches[0];if(!touch)return;startX=touch.clientX;startY=touch.clientY;isSwiping.value=true;direction.value="none";lengthX.value=0;lengthY.value=0;onSwipeStart?.(e)};const onTouchMove=(e)=>{if(!isSwiping.value)return;const touch=e.touches[0];if(!touch)return;lengthX.value=touch.clientX-startX;lengthY.value=touch.clientY-startY;const absX=Math.abs(lengthX.value);const absY=Math.abs(lengthY.value);if(absX>absY)direction.value=lengthX.value>0?"right":"left";else if(absY>absX)direction.value=lengthY.value>0?"down":"up"};const onTouchEnd=(e)=>{if(!isSwiping.value)return;isSwiping.value=false;const absX=Math.abs(lengthX.value);const absY=Math.abs(lengthY.value);const maxLength=Math.max(absX,absY);if(maxLength>=threshold){onSwipe?.(direction.value);onSwipeEnd?.(e,direction.value)}else{direction.value="none";onSwipeEnd?.(e,"none")}};el.addEventListener("touchstart",onTouchStart,{passive});el.addEventListener("touchmove",onTouchMove,{passive});el.addEventListener("touchend",onTouchEnd,{passive});el.addEventListener("touchcancel",onTouchEnd,{passive});try{onUnmounted(()=>{el.removeEventListener("touchstart",onTouchStart);el.removeEventListener("touchmove",onTouchMove);el.removeEventListener("touchend",onTouchEnd);el.removeEventListener("touchcancel",onTouchEnd)})}catch{}return{isSwiping,direction,lengthX,lengthY}}
@@ -1 +1 @@
1
- import{ref,watch}from"@stacksjs/stx";export function useTextDirection(target,initialValue){const el=target??(typeof document<"u"?document.documentElement:null);let initial=initialValue??"ltr";if(el){const dir=el.getAttribute("dir");if(dir==="rtl"||dir==="ltr"||dir==="auto")initial=dir}const direction=ref(initial);watch(direction,(val)=>{if(el)el.setAttribute("dir",val)});return direction}
1
+ import{ref,watch}from"@stacksjs/stx";export function useTextDirection(target,initialValue){const el=target??(typeof document!=="undefined"?document.documentElement:null);let initial=initialValue??"ltr";if(el){const dir=el.getAttribute("dir");if(dir==="rtl"||dir==="ltr"||dir==="auto")initial=dir}const direction=ref(initial);watch(direction,(val)=>{if(el)el.setAttribute("dir",val)});return direction}
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";export function useTextSelection(){const text=ref(""),ranges=ref([]),selection=ref(null);if(typeof document>"u")return{text,ranges,selection};const handler=()=>{const sel=document.getSelection();selection.value=sel;if(sel&&sel.rangeCount>0){text.value=sel.toString();const newRanges=[];for(let i=0;i<sel.rangeCount;i++)newRanges.push(sel.getRangeAt(i));ranges.value=newRanges}else{text.value="";ranges.value=[]}};document.addEventListener("selectionchange",handler,{passive:!0});try{onUnmounted(()=>{document.removeEventListener("selectionchange",handler)})}catch{}return{text,ranges,selection}}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";export function useTextSelection(){const text=ref("");const ranges=ref([]);const selection=ref(null);if(typeof document==="undefined")return{text,ranges,selection};const handler=()=>{const sel=document.getSelection();selection.value=sel;if(sel&&sel.rangeCount>0){text.value=sel.toString();const newRanges=[];for(let i=0;i<sel.rangeCount;i++)newRanges.push(sel.getRangeAt(i));ranges.value=newRanges}else{text.value="";ranges.value=[]}};document.addEventListener("selectionchange",handler,{passive:true});try{onUnmounted(()=>{document.removeEventListener("selectionchange",handler)})}catch{}return{text,ranges,selection}}
@@ -1 +1 @@
1
- import{ref,watch}from"@stacksjs/stx";export function useTextareaAutosize(options){const textarea=ref(options?.element??null),input=ref(options?.input??"");function triggerResize(){const el=textarea.value;if(!el)return;el.style.height="auto";el.style.height=`${el.scrollHeight}px`}watch(input,()=>{if(textarea.value)textarea.value.value=input.value;if(typeof requestAnimationFrame<"u")requestAnimationFrame(triggerResize);else triggerResize()});return{textarea,input,triggerResize}}
1
+ import{ref,watch}from"@stacksjs/stx";export function useTextareaAutosize(options){const textarea=ref(options?.element??null);const input=ref(options?.input??"");function triggerResize(){const el=textarea.value;if(!el)return;el.style.height="auto";el.style.height=`${el.scrollHeight}px`}watch(input,()=>{if(textarea.value)textarea.value.value=input.value;if(typeof requestAnimationFrame!=="undefined")requestAnimationFrame(triggerResize);else triggerResize()});return{textarea,input,triggerResize}}
@@ -1 +1 @@
1
- import{ref,watch}from"@stacksjs/stx";import{isRef,unref}from"./_shared";export function useThrottle(value,ms=200){const throttled=ref(unref(value));let lastUpdate=0,timer=null;if(isRef(value))watch(value,(newVal)=>{const now=Date.now(),elapsed=now-lastUpdate;if(elapsed>=ms){throttled.value=newVal;lastUpdate=now}else{if(timer!==null)clearTimeout(timer);timer=setTimeout(()=>{throttled.value=value.value;lastUpdate=Date.now();timer=null},ms-elapsed)}});return throttled}
1
+ import{ref,watch}from"@stacksjs/stx";import{isRef,unref}from"./_shared";export function useThrottle(value,ms=200){const throttled=ref(unref(value));let lastUpdate=0;let timer=null;if(isRef(value)){watch(value,(newVal)=>{const now=Date.now();const elapsed=now-lastUpdate;if(elapsed>=ms){throttled.value=newVal;lastUpdate=now}else{if(timer!==null)clearTimeout(timer);timer=setTimeout(()=>{throttled.value=value.value;lastUpdate=Date.now();timer=null},ms-elapsed)}})}return throttled}
@@ -1 +1 @@
1
- export function useThrottleFn(fn,ms=200){let lastExec=0,timeoutId=null,lastArgs=null,lastThis=null;const throttled=function(...args){const now=Date.now(),elapsed=now-lastExec;if(elapsed>=ms){lastExec=now;if(timeoutId!==null){clearTimeout(timeoutId);timeoutId=null}fn.apply(this,args)}else{lastArgs=args;lastThis=this;if(timeoutId===null)timeoutId=setTimeout(()=>{lastExec=Date.now();timeoutId=null;if(lastArgs!==null){fn.apply(lastThis,lastArgs);lastArgs=null;lastThis=null}},ms-elapsed)}};throttled.cancel=()=>{if(timeoutId!==null){clearTimeout(timeoutId);timeoutId=null}lastArgs=null;lastThis=null};return throttled}
1
+ export function useThrottleFn(fn,ms=200){let lastExec=0;let timeoutId=null;let lastArgs=null;let lastThis=null;const throttled=function(...args){const now=Date.now();const elapsed=now-lastExec;if(elapsed>=ms){lastExec=now;if(timeoutId!==null){clearTimeout(timeoutId);timeoutId=null}fn.apply(this,args)}else{lastArgs=args;lastThis=this;if(timeoutId===null){timeoutId=setTimeout(()=>{lastExec=Date.now();timeoutId=null;if(lastArgs!==null){fn.apply(lastThis,lastArgs);lastArgs=null;lastThis=null}},ms-elapsed)}}};throttled.cancel=()=>{if(timeoutId!==null){clearTimeout(timeoutId);timeoutId=null}lastArgs=null;lastThis=null};return throttled}
@@ -1 +1 @@
1
- import{ref,watch}from"@stacksjs/stx";export function useThrottledRef(value,delay=200){const source=ref(value),throttled=ref(value);let lastUpdate=0,timeoutId=null;watch(source,(newVal)=>{const now=Date.now(),elapsed=now-lastUpdate;if(elapsed>=delay){lastUpdate=now;throttled.value=newVal;if(timeoutId!==null){clearTimeout(timeoutId);timeoutId=null}}else if(timeoutId===null)timeoutId=setTimeout(()=>{lastUpdate=Date.now();throttled.value=source.value;timeoutId=null},delay-elapsed)});return{get value(){return throttled.value},set value(newVal){source.value=newVal},subscribe:throttled.subscribe}}
1
+ import{ref,watch}from"@stacksjs/stx";export function useThrottledRef(value,delay=200){const source=ref(value);const throttled=ref(value);let lastUpdate=0;let timeoutId=null;watch(source,(newVal)=>{const now=Date.now();const elapsed=now-lastUpdate;if(elapsed>=delay){lastUpdate=now;throttled.value=newVal;if(timeoutId!==null){clearTimeout(timeoutId);timeoutId=null}}else if(timeoutId===null){timeoutId=setTimeout(()=>{lastUpdate=Date.now();throttled.value=source.value;timeoutId=null},delay-elapsed)}});return{get value(){return throttled.value},set value(newVal){source.value=newVal},subscribe:throttled.subscribe}}
@@ -1 +1 @@
1
- import{watch}from"@stacksjs/stx";import{useManualRefHistory}from"./useManualRefHistory";export function useThrottledRefHistory(source,options){const interval=options?.throttle??200,{history,commit,undo,redo,canUndo,canRedo,clear,last}=useManualRefHistory(source,options);let lastCommit=0,timer=null,ignoreNext=!1;watch(source,()=>{if(ignoreNext){ignoreNext=!1;return}const now=Date.now();if(now-lastCommit>=interval){lastCommit=now;commit()}else{if(timer!==null)clearTimeout(timer);timer=setTimeout(()=>{timer=null;lastCommit=Date.now();commit()},interval-(now-lastCommit))}});const origUndo=undo,origRedo=redo;function throttledUndo(){if(timer!==null){clearTimeout(timer);timer=null}ignoreNext=!0;origUndo()}function throttledRedo(){if(timer!==null){clearTimeout(timer);timer=null}ignoreNext=!0;origRedo()}return{history,commit,undo:throttledUndo,redo:throttledRedo,canUndo,canRedo,clear,last}}
1
+ import{watch}from"@stacksjs/stx";import{useManualRefHistory}from"./useManualRefHistory";export function useThrottledRefHistory(source,options){const interval=options?.throttle??200;const{history,commit,undo,redo,canUndo,canRedo,clear,last}=useManualRefHistory(source,options);let lastCommit=0;let timer=null;let ignoreNext=false;watch(source,()=>{if(ignoreNext){ignoreNext=false;return}const now=Date.now();if(now-lastCommit>=interval){lastCommit=now;commit()}else{if(timer!==null)clearTimeout(timer);timer=setTimeout(()=>{timer=null;lastCommit=Date.now();commit()},interval-(now-lastCommit))}});const origUndo=undo;const origRedo=redo;function throttledUndo(){if(timer!==null){clearTimeout(timer);timer=null}ignoreNext=true;origUndo()}function throttledRedo(){if(timer!==null){clearTimeout(timer);timer=null}ignoreNext=true;origRedo()}return{history,commit,undo:throttledUndo,redo:throttledRedo,canUndo,canRedo,clear,last}}
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";import{toValue}from"./_shared";const SECOND=1000,MINUTE=60*SECOND,HOUR=60*MINUTE,DAY=24*HOUR,WEEK=7*DAY,MONTH=30*DAY,YEAR=365*DAY;function formatTimeAgo(diff){const absDiff=Math.abs(diff);if(absDiff<5*SECOND)return"just now";const isFuture=diff<0;let value,unit;if(absDiff<MINUTE){value=Math.floor(absDiff/SECOND);unit="second"}else if(absDiff<HOUR){value=Math.floor(absDiff/MINUTE);unit="minute"}else if(absDiff<DAY){value=Math.floor(absDiff/HOUR);unit="hour"}else if(absDiff<WEEK){value=Math.floor(absDiff/DAY);unit="day"}else if(absDiff<MONTH){value=Math.floor(absDiff/WEEK);unit="week"}else if(absDiff<YEAR){value=Math.floor(absDiff/MONTH);unit="month"}else{value=Math.floor(absDiff/YEAR);unit="year"}const plural=value!==1?"s":"";if(isFuture)return`in ${value} ${unit}${plural}`;return`${value} ${unit}${plural} ago`}export function useTimeAgo(date,options={}){const{updateInterval=30000}=options;function getTimestamp(){const d=toValue(date);if(d instanceof Date)return d.getTime();if(typeof d==="number")return d;return new Date(d).getTime()}function update(){const now=Date.now(),target=getTimestamp(),diff=now-target;return formatTimeAgo(diff)}const timeAgo=ref(update()),intervalId=setInterval(()=>{timeAgo.value=update()},updateInterval);try{onUnmounted(()=>clearInterval(intervalId))}catch{}return timeAgo}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";import{toValue}from"./_shared";const SECOND=1000;const MINUTE=60*SECOND;const HOUR=60*MINUTE;const DAY=24*HOUR;const WEEK=7*DAY;const MONTH=30*DAY;const YEAR=365*DAY;function formatTimeAgo(diff){const absDiff=Math.abs(diff);if(absDiff<5*SECOND){return"just now"}const isFuture=diff<0;let value;let unit;if(absDiff<MINUTE){value=Math.floor(absDiff/SECOND);unit="second"}else if(absDiff<HOUR){value=Math.floor(absDiff/MINUTE);unit="minute"}else if(absDiff<DAY){value=Math.floor(absDiff/HOUR);unit="hour"}else if(absDiff<WEEK){value=Math.floor(absDiff/DAY);unit="day"}else if(absDiff<MONTH){value=Math.floor(absDiff/WEEK);unit="week"}else if(absDiff<YEAR){value=Math.floor(absDiff/MONTH);unit="month"}else{value=Math.floor(absDiff/YEAR);unit="year"}const plural=value!==1?"s":"";if(isFuture){return`in ${value} ${unit}${plural}`}return`${value} ${unit}${plural} ago`}export function useTimeAgo(date,options={}){const{updateInterval=30000}=options;function getTimestamp(){const d=toValue(date);if(d instanceof Date)return d.getTime();if(typeof d==="number")return d;return new Date(d).getTime()}function update(){const now=Date.now();const target=getTimestamp();const diff=now-target;return formatTimeAgo(diff)}const timeAgo=ref(update());const intervalId=setInterval(()=>{timeAgo.value=update()},updateInterval);try{onUnmounted(()=>clearInterval(intervalId))}catch{}return timeAgo}
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";export function useTimeout(interval=1000,options={}){const{controls=!1,immediate=!0}=options,ready=ref(!1);let timeoutId=null;function stop(){if(timeoutId!==null){clearTimeout(timeoutId);timeoutId=null}ready.value=!1}function start(){stop();timeoutId=setTimeout(()=>{ready.value=!0;timeoutId=null},interval)}if(immediate)start();try{onUnmounted(()=>{if(timeoutId!==null){clearTimeout(timeoutId);timeoutId=null}})}catch{}if(controls)return{ready,start,stop};return ready}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";export function useTimeout(interval=1000,options={}){const{controls=false,immediate=true}=options;const ready=ref(false);let timeoutId=null;function stop(){if(timeoutId!==null){clearTimeout(timeoutId);timeoutId=null}ready.value=false}function start(){stop();timeoutId=setTimeout(()=>{ready.value=true;timeoutId=null},interval)}if(immediate){start()}try{onUnmounted(()=>{if(timeoutId!==null){clearTimeout(timeoutId);timeoutId=null}})}catch{}if(controls){return{ready,start,stop}}return ready}
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";export function useTimeoutFn(cb,interval=1000,options={}){const{immediate=!0}=options,isPending=ref(!1);let timeoutId=null;function stop(){if(timeoutId!==null){clearTimeout(timeoutId);timeoutId=null}isPending.value=!1}function start(){stop();isPending.value=!0;timeoutId=setTimeout(()=>{timeoutId=null;isPending.value=!1;cb()},interval)}if(immediate)start();try{onUnmounted(stop)}catch{}return{start,stop,isPending}}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";export function useTimeoutFn(cb,interval=1000,options={}){const{immediate=true}=options;const isPending=ref(false);let timeoutId=null;function stop(){if(timeoutId!==null){clearTimeout(timeoutId);timeoutId=null}isPending.value=false}function start(){stop();isPending.value=true;timeoutId=setTimeout(()=>{timeoutId=null;isPending.value=false;cb()},interval)}if(immediate){start()}try{onUnmounted(stop)}catch{}return{start,stop,isPending}}
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";export function useTimeoutPoll(fn,interval,options){const{immediate=!0}=options??{},isActive=ref(!1);let timer=null;async function poll(){if(!isActive.value)return;try{await fn()}catch{}if(isActive.value)timer=setTimeout(poll,interval)}function resume(){if(isActive.value)return;isActive.value=!0;poll()}function pause(){isActive.value=!1;if(timer!==null){clearTimeout(timer);timer=null}}if(immediate)resume();try{onUnmounted(()=>pause())}catch{}return{isActive,pause,resume}}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";export function useTimeoutPoll(fn,interval,options){const{immediate=true}=options??{};const isActive=ref(false);let timer=null;async function poll(){if(!isActive.value)return;try{await fn()}catch{}if(isActive.value)timer=setTimeout(poll,interval)}function resume(){if(isActive.value)return;isActive.value=true;poll()}function pause(){isActive.value=false;if(timer!==null){clearTimeout(timer);timer=null}}if(immediate)resume();try{onUnmounted(()=>pause())}catch{}return{isActive,pause,resume}}
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";export function useTimestamp(options={}){const{offset=0,interval=1000,immediate=!0}=options,timestamp=ref(Date.now()+offset);let intervalId=null,rafId=null,active=!1;function update(){timestamp.value=Date.now()+offset}function cleanup(){if(intervalId!==null){clearInterval(intervalId);intervalId=null}if(rafId!==null&&typeof cancelAnimationFrame<"u"){cancelAnimationFrame(rafId);rafId=null}active=!1}function start(){if(active)return;active=!0;update();if(interval==="requestAnimationFrame"){if(typeof requestAnimationFrame<"u"){const tick=()=>{if(!active)return;update();rafId=requestAnimationFrame(tick)};rafId=requestAnimationFrame(tick)}}else intervalId=setInterval(update,interval)}if(immediate)start();try{onUnmounted(cleanup)}catch{}return timestamp}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";export function useTimestamp(options={}){const{offset=0,interval=1000,immediate=true}=options;const timestamp=ref(Date.now()+offset);let intervalId=null;let rafId=null;let active=false;function update(){timestamp.value=Date.now()+offset}function cleanup(){if(intervalId!==null){clearInterval(intervalId);intervalId=null}if(rafId!==null&&typeof cancelAnimationFrame!=="undefined"){cancelAnimationFrame(rafId);rafId=null}active=false}function start(){if(active)return;active=true;update();if(interval==="requestAnimationFrame"){if(typeof requestAnimationFrame!=="undefined"){const tick=()=>{if(!active)return;update();rafId=requestAnimationFrame(tick)};rafId=requestAnimationFrame(tick)}}else{intervalId=setInterval(update,interval)}}if(immediate){start()}try{onUnmounted(cleanup)}catch{}return timestamp}
package/dist/useTitle.js CHANGED
@@ -1 +1 @@
1
- import{ref,watch}from"@stacksjs/stx";import{defaultDocument,toValue}from"./_shared";export function useTitle(newTitle){const doc=defaultDocument(),initialTitle=newTitle!==void 0?toValue(newTitle):doc?.title??"",title=ref(initialTitle);if(doc&&newTitle!==void 0)doc.title=title.value;watch(title,(val)=>{if(doc)doc.title=val});return title}
1
+ import{ref,watch}from"@stacksjs/stx";import{defaultDocument,toValue}from"./_shared";export function useTitle(newTitle){const doc=defaultDocument();const initialTitle=newTitle!==undefined?toValue(newTitle):doc?.title??"";const title=ref(initialTitle);if(doc&&newTitle!==undefined){doc.title=title.value}watch(title,(val)=>{if(doc){doc.title=val}});return title}
@@ -1 +1 @@
1
- import{ref,watch}from"@stacksjs/stx";import{toValue}from"./_shared";export function useToNumber(value,options={}){const{method="parseFloat",radix=10,nanToZero=!1}=options,result=ref(0);function convert(val){if(typeof val==="number")return val;let num;if(method==="parseInt")num=Number.parseInt(val,radix);else num=Number.parseFloat(val);if(nanToZero&&Number.isNaN(num))return 0;return num}result.value=convert(toValue(value));if(typeof value==="function");else if(value&&typeof value==="object"&&"value"in value&&"subscribe"in value)watch(value,(newVal)=>{result.value=convert(newVal)});return result}
1
+ import{ref,watch}from"@stacksjs/stx";import{toValue}from"./_shared";export function useToNumber(value,options={}){const{method="parseFloat",radix=10,nanToZero=false}=options;const result=ref(0);function convert(val){if(typeof val==="number")return val;let num;if(method==="parseInt")num=Number.parseInt(val,radix);else num=Number.parseFloat(val);if(nanToZero&&Number.isNaN(num))return 0;return num}result.value=convert(toValue(value));if(typeof value==="function"){}else if(value&&typeof value==="object"&&"value"in value&&"subscribe"in value){watch(value,(newVal)=>{result.value=convert(newVal)})}return result}
@@ -1 +1 @@
1
- import{ref,watch}from"@stacksjs/stx";import{isRef,toValue}from"./_shared";export function useToString(value){const result=ref(String(toValue(value)??""));if(isRef(value))watch(value,(newVal)=>{result.value=String(newVal??"")});return result}
1
+ import{ref,watch}from"@stacksjs/stx";import{isRef,toValue}from"./_shared";export function useToString(value){const result=ref(String(toValue(value)??""));if(isRef(value)){watch(value,(newVal)=>{result.value=String(newVal??"")})}return result}