@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
package/dist/useToggle.js CHANGED
@@ -1 +1 @@
1
- import{ref}from"@stacksjs/stx";export function useToggle(initialValue=!1){const state=typeof initialValue==="boolean"?ref(initialValue):initialValue;function toggle(value){if(typeof value==="boolean")state.value=value;else state.value=!state.value;return state.value}return[state,toggle]}
1
+ import{ref}from"@stacksjs/stx";export function useToggle(initialValue=false){const state=typeof initialValue==="boolean"?ref(initialValue):initialValue;function toggle(value){if(typeof value==="boolean"){state.value=value}else{state.value=!state.value}return state.value}return[state,toggle]}
@@ -1 +1 @@
1
- import{onUnmounted,ref,watch}from"@stacksjs/stx";import{unref}from"./_shared";export const TransitionPresets={linear:(t)=>t,easeInQuad:(t)=>t*t,easeOutQuad:(t)=>t*(2-t),easeInOutQuad:(t)=>t<0.5?2*t*t:-1+(4-2*t)*t,easeInCubic:(t)=>t*t*t,easeOutCubic:(t)=>--t*t*t+1,easeInOutCubic:(t)=>t<0.5?4*t*t*t:(t-1)*(2*t-2)*(2*t-2)+1};export function useTransition(source,options={}){const{duration=300,transition=TransitionPresets.linear,delay=0,onFinished,onStarted}=options,output=ref(unref(source));let rafId=null;function startTransition(from,to){if(rafId!==null)cancelAnimationFrame(rafId);const start=performance.now()+delay;onStarted?.();function tick(now){const elapsed=now-start;if(elapsed<0){rafId=requestAnimationFrame(tick);return}const progress=Math.min(elapsed/duration,1),eased=transition(progress);output.value=from+(to-from)*eased;if(progress<1)rafId=requestAnimationFrame(tick);else{rafId=null;output.value=to;onFinished?.()}}rafId=requestAnimationFrame(tick)}if(typeof source==="object"&&source&&"value"in source&&"subscribe"in source)watch(source,(newValue)=>{if(typeof requestAnimationFrame<"u")startTransition(output.value,newValue);else output.value=newValue});try{onUnmounted(()=>{if(rafId!==null)cancelAnimationFrame(rafId)})}catch{}return output}export function executeTransition(_from,_to,options={}){return new Promise((resolve)=>{const{duration=300,transition=TransitionPresets.linear,delay=0,onFinished,onStarted}=options;if(typeof requestAnimationFrame>"u"){onFinished?.();resolve();return}const start=performance.now()+delay;onStarted?.();function tick(now){const elapsed=now-start;if(elapsed<0){requestAnimationFrame(tick);return}if(Math.min(elapsed/duration,1)>=1){onFinished?.();resolve()}else requestAnimationFrame(tick)}requestAnimationFrame(tick)})}
1
+ import{onUnmounted,ref,watch}from"@stacksjs/stx";import{unref}from"./_shared";export const TransitionPresets={linear:(t)=>t,easeInQuad:(t)=>t*t,easeOutQuad:(t)=>t*(2-t),easeInOutQuad:(t)=>t<0.5?2*t*t:-1+(4-2*t)*t,easeInCubic:(t)=>t*t*t,easeOutCubic:(t)=>--t*t*t+1,easeInOutCubic:(t)=>t<0.5?4*t*t*t:(t-1)*(2*t-2)*(2*t-2)+1};export function useTransition(source,options={}){const{duration=300,transition=TransitionPresets.linear,delay=0,onFinished,onStarted}=options;const output=ref(unref(source));let rafId=null;function startTransition(from,to){if(rafId!==null)cancelAnimationFrame(rafId);const start=performance.now()+delay;onStarted?.();function tick(now){const elapsed=now-start;if(elapsed<0){rafId=requestAnimationFrame(tick);return}const progress=Math.min(elapsed/duration,1);const eased=transition(progress);output.value=from+(to-from)*eased;if(progress<1){rafId=requestAnimationFrame(tick)}else{rafId=null;output.value=to;onFinished?.()}}rafId=requestAnimationFrame(tick)}if(typeof source==="object"&&source&&"value"in source&&"subscribe"in source){watch(source,(newValue)=>{if(typeof requestAnimationFrame!=="undefined")startTransition(output.value,newValue);else output.value=newValue})}try{onUnmounted(()=>{if(rafId!==null)cancelAnimationFrame(rafId)})}catch{}return output}export function executeTransition(_from,_to,options={}){return new Promise((resolve)=>{const{duration=300,transition=TransitionPresets.linear,delay=0,onFinished,onStarted}=options;if(typeof requestAnimationFrame==="undefined"){onFinished?.();resolve();return}const start=performance.now()+delay;onStarted?.();function tick(now){const elapsed=now-start;if(elapsed<0){requestAnimationFrame(tick);return}const progress=Math.min(elapsed/duration,1);if(progress>=1){onFinished?.();resolve()}else{requestAnimationFrame(tick)}}requestAnimationFrame(tick)})}
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";import{defaultWindow}from"./_shared";export function useUrlSearchParams(mode="history",options){const win=defaultWindow(),{initialValue}=options??{};function readParams(){if(!win)return{...initialValue};let search="";if(mode==="hash"){const hash=win.location.hash,idx=hash.indexOf("?");search=idx>=0?hash.slice(idx+1):""}else search=win.location.search.slice(1);const result={...initialValue};new URLSearchParams(search).forEach((value,key)=>{result[key]=value});return result}const params=ref(readParams());function writeParams(){if(!win)return;const searchParams=new URLSearchParams;for(const[key,value]of Object.entries(params.value))if(value!==void 0&&value!==null&&value!=="")searchParams.set(key,value);const query=searchParams.toString();if(mode==="hash"){const basePath=win.location.hash.split("?")[0]||"#";win.location.hash=query?`${basePath}?${query}`:basePath}else{const url=query?`${win.location.pathname}?${query}`:win.location.pathname;win.history.replaceState(win.history.state,"",url)}}function get(key){return params.value[key]??null}function set(key,value){const current={...params.value};current[key]=value;params.value=current;writeParams()}function del(key){const current={...params.value};delete current[key];params.value=current;writeParams()}if(win){const onPopState=()=>{params.value=readParams()},onHashChange=()=>{if(mode==="hash")params.value=readParams()};win.addEventListener("popstate",onPopState);win.addEventListener("hashchange",onHashChange);onUnmounted(()=>{win.removeEventListener("popstate",onPopState);win.removeEventListener("hashchange",onHashChange)})}return{params,get,set,delete:del}}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";import{defaultWindow}from"./_shared";export function useUrlSearchParams(mode="history",options){const win=defaultWindow();const{initialValue}=options??{};function readParams(){if(!win)return{...initialValue};let search="";if(mode==="hash"){const hash=win.location.hash;const idx=hash.indexOf("?");search=idx>=0?hash.slice(idx+1):""}else{search=win.location.search.slice(1)}const result={...initialValue};const searchParams=new URLSearchParams(search);searchParams.forEach((value,key)=>{result[key]=value});return result}const params=ref(readParams());function writeParams(){if(!win)return;const searchParams=new URLSearchParams;for(const[key,value]of Object.entries(params.value)){if(value!==undefined&&value!==null&&value!==""){searchParams.set(key,value)}}const query=searchParams.toString();if(mode==="hash"){const basePath=win.location.hash.split("?")[0]||"#";win.location.hash=query?`${basePath}?${query}`:basePath}else{const url=query?`${win.location.pathname}?${query}`:win.location.pathname;win.history.replaceState(win.history.state,"",url)}}function get(key){return params.value[key]??null}function set(key,value){const current={...params.value};current[key]=value;params.value=current;writeParams()}function del(key){const current={...params.value};delete current[key];params.value=current;writeParams()}if(win){const onPopState=()=>{params.value=readParams()};const onHashChange=()=>{if(mode==="hash"){params.value=readParams()}};win.addEventListener("popstate",onPopState);win.addEventListener("hashchange",onHashChange);onUnmounted(()=>{win.removeEventListener("popstate",onPopState);win.removeEventListener("hashchange",onHashChange)})}return{params,get,set,delete:del}}
@@ -1 +1 @@
1
- import{ref}from"@stacksjs/stx";export function useVibrate(options={}){const{pattern=200}=options,isSupported=ref(typeof navigator<"u"&&"vibrate"in navigator);function vibrate(p){if(!isSupported.value)return!1;return navigator.vibrate(p??pattern)}function stop(){if(isSupported.value)navigator.vibrate(0)}return{isSupported,vibrate,stop}}
1
+ import{ref}from"@stacksjs/stx";export function useVibrate(options={}){const{pattern=200}=options;const isSupported=ref(typeof navigator!=="undefined"&&"vibrate"in navigator);function vibrate(p){if(!isSupported.value)return false;return navigator.vibrate(p??pattern)}function stop(){if(isSupported.value)navigator.vibrate(0)}return{isSupported,vibrate,stop}}
@@ -1 +1 @@
1
- import{ref,watch}from"@stacksjs/stx";import{unref}from"./_shared";export function useVirtualList(source,options){const{itemHeight,overscan=5}=options,list=ref([]),containerHeight=ref(0),scrollTop=ref(0),wrapperProps=ref({style:{width:"100%",height:"0px",marginTop:"0px"}});function getItems(){return unref(source)}function update(){const items=getItems(),totalHeight=items.length*itemHeight,startIndex=Math.max(0,Math.floor(scrollTop.value/itemHeight)-overscan),endIndex=Math.min(items.length,Math.ceil((scrollTop.value+containerHeight.value)/itemHeight)+overscan),visibleItems=[];for(let i=startIndex;i<endIndex;i++){const data=items[i];if(data===void 0&&!(i in items))continue;visibleItems.push({data,index:i})}list.value=visibleItems;wrapperProps.value={style:{width:"100%",height:`${totalHeight-startIndex*itemHeight}px`,marginTop:`${startIndex*itemHeight}px`}}}const onScroll=(e)=>{const target=e.target;scrollTop.value=target.scrollTop;containerHeight.value=target.clientHeight;update()};update();if(typeof source==="object"&&source&&"value"in source&&"subscribe"in source)watch(source,()=>update());function scrollTo(index){scrollTop.value=index*itemHeight;update()}return{list,containerProps:{onScroll,style:{overflow:"auto",position:"relative"}},wrapperProps,scrollTo}}
1
+ import{ref,watch}from"@stacksjs/stx";import{unref}from"./_shared";export function useVirtualList(source,options){const{itemHeight,overscan=5}=options;const list=ref([]);const containerHeight=ref(0);const scrollTop=ref(0);const wrapperProps=ref({style:{width:"100%",height:"0px",marginTop:"0px"}});function getItems(){return unref(source)}function update(){const items=getItems();const totalHeight=items.length*itemHeight;const startIndex=Math.max(0,Math.floor(scrollTop.value/itemHeight)-overscan);const endIndex=Math.min(items.length,Math.ceil((scrollTop.value+containerHeight.value)/itemHeight)+overscan);const visibleItems=[];for(let i=startIndex;i<endIndex;i++){const data=items[i];if(data===undefined&&!(i in items))continue;visibleItems.push({data,index:i})}list.value=visibleItems;wrapperProps.value={style:{width:"100%",height:`${totalHeight-startIndex*itemHeight}px`,marginTop:`${startIndex*itemHeight}px`}}}const onScroll=(e)=>{const target=e.target;scrollTop.value=target.scrollTop;containerHeight.value=target.clientHeight;update()};update();if(typeof source==="object"&&source&&"value"in source&&"subscribe"in source){watch(source,()=>update())}function scrollTo(index){scrollTop.value=index*itemHeight;update()}return{list,containerProps:{onScroll,style:{overflow:"auto",position:"relative"}},wrapperProps,scrollTo}}
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";export function useWakeLock(){const isSupported=ref(typeof navigator<"u"&&"wakeLock"in navigator),isActive=ref(!1);let sentinel=null;async function request(){if(!isSupported.value)return;try{sentinel=await navigator.wakeLock.request("screen");isActive.value=!0;sentinel.addEventListener("release",()=>{isActive.value=!1;sentinel=null})}catch{isActive.value=!1}}async function release(){if(sentinel){await sentinel.release();sentinel=null;isActive.value=!1}}try{onUnmounted(()=>{release()})}catch{}return{isSupported,isActive,request,release}}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";export function useWakeLock(){const isSupported=ref(typeof navigator!=="undefined"&&"wakeLock"in navigator);const isActive=ref(false);let sentinel=null;async function request(){if(!isSupported.value)return;try{sentinel=await navigator.wakeLock.request("screen");isActive.value=true;sentinel.addEventListener("release",()=>{isActive.value=false;sentinel=null})}catch{isActive.value=false}}async function release(){if(sentinel){await sentinel.release();sentinel=null;isActive.value=false}}try{onUnmounted(()=>{release()})}catch{}return{isSupported,isActive,request,release}}
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";export function useWebNotification(options={}){const isSupported=ref(typeof Notification<"u"),notification=ref(null),permissionGranted=ref(isSupported.value&&Notification.permission==="granted"),onClick=ref(null),onShow=ref(null),onError=ref(null),onClose=ref(null);async function show(overrideOptions){if(!isSupported.value)return;if(Notification.permission!=="granted"){const result=await Notification.requestPermission();permissionGranted.value=result==="granted";if(!permissionGranted.value)return}const opts={...options,...overrideOptions},title=opts.title??"",n=new Notification(title,{body:opts.body,icon:opts.icon,dir:opts.dir,lang:opts.lang,tag:opts.tag,requireInteraction:opts.requireInteraction});notification.value=n;n.onclick=(e)=>onClick.value?.(e);n.onshow=(e)=>onShow.value?.(e);n.onerror=(e)=>onError.value?.(e);n.onclose=(e)=>{onClose.value?.(e);notification.value=null};return n}function close(){notification.value?.close();notification.value=null}try{onUnmounted(()=>close())}catch{}return{isSupported,notification,permissionGranted,show,close,onClick,onShow,onError,onClose}}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";export function useWebNotification(options={}){const isSupported=ref(typeof Notification!=="undefined");const notification=ref(null);const permissionGranted=ref(isSupported.value&&Notification.permission==="granted");const onClick=ref(null);const onShow=ref(null);const onError=ref(null);const onClose=ref(null);async function show(overrideOptions){if(!isSupported.value)return;if(Notification.permission!=="granted"){const result=await Notification.requestPermission();permissionGranted.value=result==="granted";if(!permissionGranted.value)return}const opts={...options,...overrideOptions};const title=opts.title??"";const n=new Notification(title,{body:opts.body,icon:opts.icon,dir:opts.dir,lang:opts.lang,tag:opts.tag,requireInteraction:opts.requireInteraction});notification.value=n;n.onclick=(e)=>onClick.value?.(e);n.onshow=(e)=>onShow.value?.(e);n.onerror=(e)=>onError.value?.(e);n.onclose=(e)=>{onClose.value?.(e);notification.value=null};return n}function close(){notification.value?.close();notification.value=null}try{onUnmounted(()=>close())}catch{}return{isSupported,notification,permissionGranted,show,close,onClick,onShow,onError,onClose}}
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";import{toValue}from"./_shared";export function useWebSocket(url,options={}){const{onConnected,onDisconnected,onError,onMessage,immediate=!0,autoReconnect=!1,heartbeat=!1,protocols}=options,data=ref(null),status=ref("CLOSED"),wsRef=ref(null);let retryCount=0,retryTimer=null,heartbeatTimer=null,explicitlyClosed=!1;const heartbeatInterval=typeof heartbeat==="object"?heartbeat.interval??30000:30000,heartbeatMessage=typeof heartbeat==="object"?heartbeat.message??"ping":"ping",maxRetries=typeof autoReconnect==="object"?autoReconnect.retries??3:autoReconnect?1/0:0,retryDelay=typeof autoReconnect==="object"?autoReconnect.delay??1000:1000;function startHeartbeat(ws){stopHeartbeat();if(!heartbeat)return;heartbeatTimer=setInterval(()=>{if(ws.readyState===WebSocket.OPEN)ws.send(heartbeatMessage)},heartbeatInterval)}function stopHeartbeat(){if(heartbeatTimer!==null){clearInterval(heartbeatTimer);heartbeatTimer=null}}function open(){if(typeof WebSocket>"u")return;close();explicitlyClosed=!1;retryCount=0;const resolvedUrl=toValue(url);status.value="CONNECTING";const ws=protocols?new WebSocket(resolvedUrl,protocols):new WebSocket(resolvedUrl);wsRef.value=ws;ws.onopen=()=>{status.value="OPEN";retryCount=0;startHeartbeat(ws);onConnected?.(ws)};ws.onclose=(event)=>{status.value="CLOSED";wsRef.value=null;stopHeartbeat();onDisconnected?.(ws,event);if(!explicitlyClosed&&autoReconnect&&retryCount<maxRetries){retryCount++;retryTimer=setTimeout(()=>{open()},retryDelay)}};ws.onerror=(event)=>{onError?.(ws,event)};ws.onmessage=(event)=>{data.value=typeof event.data==="string"?event.data:String(event.data);onMessage?.(ws,event)}}function close(code,reason){explicitlyClosed=!0;stopHeartbeat();if(retryTimer!==null){clearTimeout(retryTimer);retryTimer=null}const ws=wsRef.value;if(ws){if(ws.readyState===WebSocket.OPEN||ws.readyState===WebSocket.CONNECTING){status.value="CLOSING";ws.close(code,reason)}wsRef.value=null}}function send(sendData){const ws=wsRef.value;if(ws&&ws.readyState===WebSocket.OPEN)ws.send(sendData)}if(immediate)open();try{onUnmounted(()=>{close()})}catch{}return{data,status,ws:wsRef,open,close,send}}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";import{toValue}from"./_shared";export function useWebSocket(url,options={}){const{onConnected,onDisconnected,onError,onMessage,immediate=true,autoReconnect=false,heartbeat=false,protocols}=options;const data=ref(null);const status=ref("CLOSED");const wsRef=ref(null);let retryCount=0;let retryTimer=null;let heartbeatTimer=null;let explicitlyClosed=false;const heartbeatInterval=typeof heartbeat==="object"?heartbeat.interval??30000:30000;const heartbeatMessage=typeof heartbeat==="object"?heartbeat.message??"ping":"ping";const maxRetries=typeof autoReconnect==="object"?autoReconnect.retries??3:autoReconnect?1/0:0;const retryDelay=typeof autoReconnect==="object"?autoReconnect.delay??1000:1000;function startHeartbeat(ws){stopHeartbeat();if(!heartbeat)return;heartbeatTimer=setInterval(()=>{if(ws.readyState===WebSocket.OPEN){ws.send(heartbeatMessage)}},heartbeatInterval)}function stopHeartbeat(){if(heartbeatTimer!==null){clearInterval(heartbeatTimer);heartbeatTimer=null}}function open(){if(typeof WebSocket==="undefined")return;close();explicitlyClosed=false;retryCount=0;const resolvedUrl=toValue(url);status.value="CONNECTING";const ws=protocols?new WebSocket(resolvedUrl,protocols):new WebSocket(resolvedUrl);wsRef.value=ws;ws.onopen=()=>{status.value="OPEN";retryCount=0;startHeartbeat(ws);onConnected?.(ws)};ws.onclose=(event)=>{status.value="CLOSED";wsRef.value=null;stopHeartbeat();onDisconnected?.(ws,event);if(!explicitlyClosed&&autoReconnect&&retryCount<maxRetries){retryCount++;retryTimer=setTimeout(()=>{open()},retryDelay)}};ws.onerror=(event)=>{onError?.(ws,event)};ws.onmessage=(event)=>{data.value=typeof event.data==="string"?event.data:String(event.data);onMessage?.(ws,event)}}function close(code,reason){explicitlyClosed=true;stopHeartbeat();if(retryTimer!==null){clearTimeout(retryTimer);retryTimer=null}const ws=wsRef.value;if(ws){if(ws.readyState===WebSocket.OPEN||ws.readyState===WebSocket.CONNECTING){status.value="CLOSING";ws.close(code,reason)}wsRef.value=null}}function send(sendData){const ws=wsRef.value;if(ws&&ws.readyState===WebSocket.OPEN){ws.send(sendData)}}if(immediate){open()}try{onUnmounted(()=>{close()})}catch{}return{data,status,ws:wsRef,open,close,send}}
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";export function useWebWorker(url,workerOptions){const data=ref(null),worker=ref(void 0);if(typeof Worker<"u"){const w=new Worker(url,workerOptions);worker.value=w;w.onmessage=(e)=>{data.value=e.data};try{onUnmounted(()=>w.terminate())}catch{}}function post(message){worker.value?.postMessage(message)}function terminate(){worker.value?.terminate();worker.value=void 0}return{data,post,terminate,worker}}export function useWebWorkerFn(fn){let worker;function createWorker(){const blob=new Blob([`self.onmessage = function(e) { self.postMessage((${fn.toString()})(...e.data)); }`],{type:"text/javascript"}),url=URL.createObjectURL(blob);return new Worker(url)}function workerFn(...args){return new Promise((resolve,reject)=>{if(typeof Worker>"u"){try{resolve(fn(...args))}catch(e){reject(e)}return}worker=createWorker();worker.onmessage=(e)=>{resolve(e.data);worker?.terminate()};worker.onerror=(e)=>{reject(e);worker?.terminate()};worker.postMessage(args)})}function terminate(){worker?.terminate();worker=void 0}return{workerFn,terminate}}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";export function useWebWorker(url,workerOptions){const data=ref(null);const worker=ref(undefined);if(typeof Worker!=="undefined"){const w=new Worker(url,workerOptions);worker.value=w;w.onmessage=(e)=>{data.value=e.data};try{onUnmounted(()=>w.terminate())}catch{}}function post(message){worker.value?.postMessage(message)}function terminate(){worker.value?.terminate();worker.value=undefined}return{data,post,terminate,worker}}export function useWebWorkerFn(fn){let worker;function createWorker(){const blob=new Blob([`self.onmessage = function(e) { self.postMessage((${fn.toString()})(...e.data)); }`],{type:"text/javascript"});const url=URL.createObjectURL(blob);return new Worker(url)}function workerFn(...args){return new Promise((resolve,reject)=>{if(typeof Worker==="undefined"){try{resolve(fn(...args))}catch(e){reject(e)}return}worker=createWorker();worker.onmessage=(e)=>{resolve(e.data);worker?.terminate()};worker.onerror=(e)=>{reject(e);worker?.terminate()};worker.postMessage(args)})}function terminate(){worker?.terminate();worker=undefined}return{workerFn,terminate}}
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";export function useWindowFocus(){const focused=ref(typeof document<"u"?document.hasFocus():!1);if(typeof window>"u")return focused;const onFocus=()=>{focused.value=!0},onBlur=()=>{focused.value=!1};window.addEventListener("focus",onFocus,{passive:!0});window.addEventListener("blur",onBlur,{passive:!0});try{onUnmounted(()=>{window.removeEventListener("focus",onFocus);window.removeEventListener("blur",onBlur)})}catch{}return focused}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";export function useWindowFocus(){const focused=ref(typeof document!=="undefined"?document.hasFocus():false);if(typeof window==="undefined")return focused;const onFocus=()=>{focused.value=true};const onBlur=()=>{focused.value=false};window.addEventListener("focus",onFocus,{passive:true});window.addEventListener("blur",onBlur,{passive:true});try{onUnmounted(()=>{window.removeEventListener("focus",onFocus);window.removeEventListener("blur",onBlur)})}catch{}return focused}
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";export function useWindowScroll(){const x=ref(typeof window<"u"?window.scrollX:0),y=ref(typeof window<"u"?window.scrollY:0);if(typeof window>"u")return{x,y};const handler=()=>{x.value=window.scrollX;y.value=window.scrollY};window.addEventListener("scroll",handler,{passive:!0});try{onUnmounted(()=>{window.removeEventListener("scroll",handler)})}catch{}return{x,y}}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";export function useWindowScroll(){const x=ref(typeof window!=="undefined"?window.scrollX:0);const y=ref(typeof window!=="undefined"?window.scrollY:0);if(typeof window==="undefined")return{x,y};const handler=()=>{x.value=window.scrollX;y.value=window.scrollY};window.addEventListener("scroll",handler,{passive:true});try{onUnmounted(()=>{window.removeEventListener("scroll",handler)})}catch{}return{x,y}}
@@ -1 +1 @@
1
- import{onUnmounted,ref}from"@stacksjs/stx";import{defaultWindow}from"./_shared";export function useWindowSize(options){const{initialWidth=0,initialHeight=0,listenOrientation=!0}=options??{},win=defaultWindow(),width=ref(win?win.innerWidth:initialWidth),height=ref(win?win.innerHeight:initialHeight);function update(){if(win){width.value=win.innerWidth;height.value=win.innerHeight}}if(win){win.addEventListener("resize",update);if(listenOrientation)win.addEventListener("orientationchange",update);try{onUnmounted(()=>{win.removeEventListener("resize",update);if(listenOrientation)win.removeEventListener("orientationchange",update)})}catch{}}return{width,height}}
1
+ import{onUnmounted,ref}from"@stacksjs/stx";import{defaultWindow}from"./_shared";export function useWindowSize(options){const{initialWidth=0,initialHeight=0,listenOrientation=true}=options??{};const win=defaultWindow();const width=ref(win?win.innerWidth:initialWidth);const height=ref(win?win.innerHeight:initialHeight);function update(){if(win){width.value=win.innerWidth;height.value=win.innerHeight}}if(win){win.addEventListener("resize",update);if(listenOrientation){win.addEventListener("orientationchange",update)}try{onUnmounted(()=>{win.removeEventListener("resize",update);if(listenOrientation){win.removeEventListener("orientationchange",update)}})}catch{}}return{width,height}}
@@ -1 +1 @@
1
- import{watch}from"@stacksjs/stx";export function watchArray(source,callback){let oldList=[...source.value];return watch(source,(newValue)=>{const newList=[...newValue],added=newList.filter((item)=>!oldList.includes(item)),removed=oldList.filter((item)=>!newList.includes(item));callback(newList,oldList,added,removed);oldList=newList})}
1
+ import{watch}from"@stacksjs/stx";export function watchArray(source,callback){let oldList=[...source.value];const unwatch=watch(source,(newValue)=>{const newList=[...newValue];const added=newList.filter((item)=>!oldList.includes(item));const removed=oldList.filter((item)=>!newList.includes(item));callback(newList,oldList,added,removed);oldList=newList});return unwatch}
@@ -1 +1 @@
1
- import{ref,watch}from"@stacksjs/stx";export function watchAtMost(source,callback,count){const remaining=ref(count),unwatch=watch(source,(newValue)=>{if(remaining.value>0){remaining.value--;callback(newValue);if(remaining.value<=0)unwatch()}});return{stop:unwatch,remaining}}
1
+ import{ref,watch}from"@stacksjs/stx";export function watchAtMost(source,callback,count){const remaining=ref(count);const unwatch=watch(source,(newValue)=>{if(remaining.value>0){remaining.value--;callback(newValue);if(remaining.value<=0)unwatch()}});return{stop:unwatch,remaining}}
@@ -1 +1 @@
1
- import{watch}from"@stacksjs/stx";export function watchDebounced(source,callback,options){const delay=options?.debounce??200;let timeoutId=null;const unwatch=watch(source,(newValue)=>{if(timeoutId!==null)clearTimeout(timeoutId);timeoutId=setTimeout(()=>{timeoutId=null;callback(newValue)},delay)});return()=>{if(timeoutId!==null){clearTimeout(timeoutId);timeoutId=null}unwatch()}}
1
+ import{watch}from"@stacksjs/stx";export function watchDebounced(source,callback,options){const delay=options?.debounce??200;let timeoutId=null;const unwatch=watch(source,(newValue)=>{if(timeoutId!==null){clearTimeout(timeoutId)}timeoutId=setTimeout(()=>{timeoutId=null;callback(newValue)},delay)});return()=>{if(timeoutId!==null){clearTimeout(timeoutId);timeoutId=null}unwatch()}}
package/dist/watchDeep.js CHANGED
@@ -1 +1 @@
1
- import{watch}from"@stacksjs/stx";export function watchDeep(source,callback,options){let prev=JSON.stringify(source.value);if(options?.immediate)callback(source.value);return watch(source,(newValue)=>{const next=JSON.stringify(newValue);if(next!==prev){prev=next;callback(newValue)}})}
1
+ import{watch}from"@stacksjs/stx";export function watchDeep(source,callback,options){let prev=JSON.stringify(source.value);if(options?.immediate)callback(source.value);const unwatch=watch(source,(newValue)=>{const next=JSON.stringify(newValue);if(next!==prev){prev=next;callback(newValue)}});return unwatch}
@@ -1 +1 @@
1
- import{ref,watch}from"@stacksjs/stx";export function watchIgnorable(source,callback){const isIgnoring=ref(!1);let lastValue;const unwatch=watch(source,(newValue)=>{if(!isIgnoring.value)callback(newValue,lastValue);lastValue=newValue});function ignoreUpdates(updater){isIgnoring.value=!0;updater();Promise.resolve().then(()=>{isIgnoring.value=!1})}return{stop:unwatch,ignoreUpdates,isIgnoring}}export const ignorableWatch=watchIgnorable;
1
+ import{ref,watch}from"@stacksjs/stx";export function watchIgnorable(source,callback){const isIgnoring=ref(false);let lastValue;const unwatch=watch(source,(newValue)=>{if(!isIgnoring.value)callback(newValue,lastValue);lastValue=newValue});function ignoreUpdates(updater){isIgnoring.value=true;updater();Promise.resolve().then(()=>{isIgnoring.value=false})}return{stop:unwatch,ignoreUpdates,isIgnoring}}export const ignorableWatch=watchIgnorable;
package/dist/watchOnce.js CHANGED
@@ -1 +1 @@
1
- import{watch}from"@stacksjs/stx";export function watchOnce(source,callback){let stopped=!1;const unwatch=watch(source,(newValue)=>{if(stopped)return;stopped=!0;unwatch();callback(newValue)});return()=>{if(!stopped){stopped=!0;unwatch()}}}
1
+ import{watch}from"@stacksjs/stx";export function watchOnce(source,callback){let stopped=false;const unwatch=watch(source,(newValue)=>{if(stopped)return;stopped=true;unwatch();callback(newValue)});return()=>{if(!stopped){stopped=true;unwatch()}}}
@@ -1 +1 @@
1
- import{ref,watch}from"@stacksjs/stx";export function watchPausable(source,callback){const isActive=ref(!0);let lastValue;const unwatch=watch(source,(newValue)=>{if(isActive.value)callback(newValue,lastValue);lastValue=newValue});function pause(){isActive.value=!1}function resume(){isActive.value=!0}return{stop:unwatch,pause,resume,isActive}}export const pausableWatch=watchPausable;
1
+ import{ref,watch}from"@stacksjs/stx";export function watchPausable(source,callback){const isActive=ref(true);let lastValue;const unwatch=watch(source,(newValue)=>{if(isActive.value){callback(newValue,lastValue)}lastValue=newValue});function pause(){isActive.value=false}function resume(){isActive.value=true}return{stop:unwatch,pause,resume,isActive}}export const pausableWatch=watchPausable;
@@ -1 +1 @@
1
- import{watch}from"@stacksjs/stx";export function watchThrottled(source,callback,options){const interval=options?.throttle??200;let lastExec=0,timeoutId=null,latestValue,hasPending=!1;const unwatch=watch(source,(newValue)=>{const now=Date.now(),elapsed=now-lastExec;if(elapsed>=interval){lastExec=now;if(timeoutId!==null){clearTimeout(timeoutId);timeoutId=null}hasPending=!1;callback(newValue)}else{latestValue=newValue;hasPending=!0;if(timeoutId===null)timeoutId=setTimeout(()=>{lastExec=Date.now();timeoutId=null;if(hasPending){hasPending=!1;callback(latestValue)}},interval-elapsed)}});return()=>{if(timeoutId!==null){clearTimeout(timeoutId);timeoutId=null}hasPending=!1;unwatch()}}
1
+ import{watch}from"@stacksjs/stx";export function watchThrottled(source,callback,options){const interval=options?.throttle??200;let lastExec=0;let timeoutId=null;let latestValue;let hasPending=false;const unwatch=watch(source,(newValue)=>{const now=Date.now();const elapsed=now-lastExec;if(elapsed>=interval){lastExec=now;if(timeoutId!==null){clearTimeout(timeoutId);timeoutId=null}hasPending=false;callback(newValue)}else{latestValue=newValue;hasPending=true;if(timeoutId===null){timeoutId=setTimeout(()=>{lastExec=Date.now();timeoutId=null;if(hasPending){hasPending=false;callback(latestValue)}},interval-elapsed)}}});return()=>{if(timeoutId!==null){clearTimeout(timeoutId);timeoutId=null}hasPending=false;unwatch()}}
@@ -1 +1 @@
1
- import{watch}from"@stacksjs/stx";export function watchWithFilter(source,callback,eventFilter){return watch(source,(newValue)=>{eventFilter(()=>callback(newValue))})}
1
+ import{watch}from"@stacksjs/stx";export function watchWithFilter(source,callback,eventFilter){const unwatch=watch(source,(newValue)=>{eventFilter(()=>callback(newValue))});return unwatch}
package/dist/whenever.js CHANGED
@@ -1 +1 @@
1
- import{watch}from"@stacksjs/stx";export function whenever(source,callback){return watch(source,(newValue)=>{if(newValue)callback(newValue)})}
1
+ import{watch}from"@stacksjs/stx";export function whenever(source,callback){const unwatch=watch(source,(newValue)=>{if(newValue){callback(newValue)}});return unwatch}
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@stacksjs/composables",
3
3
  "type": "module",
4
4
  "sideEffects": false,
5
- "version": "0.75.515",
5
+ "version": "0.75.518",
6
6
  "description": "Stacks composables powered by stx reactivity.",
7
7
  "author": "Chris Breuer",
8
8
  "contributors": [
@@ -52,7 +52,7 @@
52
52
  },
53
53
  "dependencies": {
54
54
  "@stacksjs/stx": "0.2.807",
55
- "@stacksjs/datetime": "0.75.515"
55
+ "@stacksjs/datetime": "0.75.518"
56
56
  },
57
57
  "devDependencies": {
58
58
  "better-dx": "^0.2.24"