@stacksjs/composables 0.70.87 → 0.70.90

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 (333) hide show
  1. package/dist/_shared.d.ts +49 -0
  2. package/dist/_shared.js +23 -0
  3. package/dist/cloneFnJSON.d.ts +5 -0
  4. package/dist/cloneFnJSON.js +3 -0
  5. package/dist/computedAsync.d.ts +28 -0
  6. package/dist/computedAsync.js +20 -0
  7. package/dist/computedEager.d.ts +27 -0
  8. package/dist/computedEager.js +10 -0
  9. package/dist/createEventHook.d.ts +16 -0
  10. package/dist/createEventHook.js +15 -0
  11. package/dist/createFetch.d.ts +14 -0
  12. package/dist/createFetch.js +8 -0
  13. package/dist/createGlobalState.d.ts +17 -0
  14. package/dist/createGlobalState.js +10 -0
  15. package/dist/createSharedComposable.d.ts +8 -0
  16. package/dist/createSharedComposable.js +9 -0
  17. package/dist/extendRef.d.ts +9 -0
  18. package/dist/extendRef.js +6 -0
  19. package/dist/formatTimeAgo.d.ts +23 -0
  20. package/dist/formatTimeAgo.js +33 -0
  21. package/dist/index.d.ts +271 -0
  22. package/dist/index.js +210 -2
  23. package/dist/isDefined.d.ts +5 -0
  24. package/dist/isDefined.js +3 -0
  25. package/dist/makeDestructurable.d.ts +18 -0
  26. package/dist/makeDestructurable.js +16 -0
  27. package/dist/onClickOutside.d.ts +14 -0
  28. package/dist/onClickOutside.js +25 -0
  29. package/dist/onKeyStroke.d.ts +26 -0
  30. package/dist/onKeyStroke.js +31 -0
  31. package/dist/onLongPress.d.ts +14 -0
  32. package/dist/onLongPress.js +43 -0
  33. package/dist/onStartTyping.d.ts +8 -0
  34. package/dist/onStartTyping.js +23 -0
  35. package/dist/refAutoReset.d.ts +11 -0
  36. package/dist/refAutoReset.js +15 -0
  37. package/dist/refDefault.d.ts +9 -0
  38. package/dist/refDefault.js +8 -0
  39. package/dist/resolveRef.d.ts +7 -0
  40. package/dist/resolveRef.js +7 -0
  41. package/dist/ssrHandlers.d.ts +13 -0
  42. package/dist/ssrHandlers.js +8 -0
  43. package/dist/syncRef.d.ts +21 -0
  44. package/dist/syncRef.js +35 -0
  45. package/dist/tryOnMounted.d.ts +22 -0
  46. package/dist/tryOnMounted.js +22 -0
  47. package/dist/unrefElement.d.ts +6 -0
  48. package/dist/unrefElement.js +9 -0
  49. package/dist/until.d.ts +34 -0
  50. package/dist/until.js +62 -0
  51. package/dist/useActiveElement.d.ts +6 -0
  52. package/dist/useActiveElement.js +19 -0
  53. package/dist/useAnimate.d.ts +18 -0
  54. package/dist/useAnimate.js +48 -0
  55. package/dist/useArrayUtils.d.ts +42 -0
  56. package/dist/useArrayUtils.js +114 -0
  57. package/dist/useAsyncQueue.d.ts +18 -0
  58. package/dist/useAsyncQueue.js +22 -0
  59. package/dist/useAsyncState.d.ts +23 -0
  60. package/dist/useAsyncState.js +35 -0
  61. package/dist/useBase64.d.ts +12 -0
  62. package/dist/useBase64.js +45 -0
  63. package/dist/useBattery.d.ts +15 -0
  64. package/dist/useBattery.js +38 -0
  65. package/dist/useBreakpoints.d.ts +96 -0
  66. package/dist/useBreakpoints.js +97 -0
  67. package/dist/useBroadcastChannel.d.ts +14 -0
  68. package/dist/useBroadcastChannel.js +31 -0
  69. package/dist/useBrowserLocation.d.ts +18 -0
  70. package/dist/useBrowserLocation.js +64 -0
  71. package/dist/useClipboard.d.ts +17 -0
  72. package/dist/useClipboard.js +32 -0
  73. package/dist/useClipboardItems.d.ts +11 -0
  74. package/dist/useClipboardItems.js +15 -0
  75. package/dist/useCloned.d.ts +15 -0
  76. package/dist/useCloned.js +16 -0
  77. package/dist/useColorMode.d.ts +18 -0
  78. package/dist/useColorMode.js +60 -0
  79. package/dist/useConfirmDialog.d.ts +14 -0
  80. package/dist/useConfirmDialog.js +34 -0
  81. package/dist/useCounter.d.ts +20 -0
  82. package/dist/useCounter.js +28 -0
  83. package/dist/useCssVar.d.ts +10 -0
  84. package/dist/useCssVar.js +23 -0
  85. package/dist/useCycleList.d.ts +18 -0
  86. package/dist/useCycleList.js +27 -0
  87. package/dist/useDark.d.ts +11 -0
  88. package/dist/useDark.js +38 -0
  89. package/dist/useDateFormat.d.ts +10 -0
  90. package/dist/useDateFormat.js +11 -0
  91. package/dist/useDebounce.d.ts +10 -0
  92. package/dist/useDebounce.js +16 -0
  93. package/dist/useDebounceFn.d.ts +10 -0
  94. package/dist/useDebounceFn.js +18 -0
  95. package/dist/useDebouncedRef.d.ts +11 -0
  96. package/dist/useDebouncedRef.js +22 -0
  97. package/dist/useDebouncedRefHistory.d.ts +5 -0
  98. package/dist/useDebouncedRefHistory.js +36 -0
  99. package/dist/useDeviceMotion.d.ts +27 -0
  100. package/dist/useDeviceMotion.js +53 -0
  101. package/dist/useDeviceOrientation.d.ts +15 -0
  102. package/dist/useDeviceOrientation.js +23 -0
  103. package/dist/useDevicePixelRatio.d.ts +5 -0
  104. package/dist/useDevicePixelRatio.js +24 -0
  105. package/dist/useDocumentVisibility.d.ts +5 -0
  106. package/dist/useDocumentVisibility.js +16 -0
  107. package/dist/useDraggable.d.ts +23 -0
  108. package/dist/useDraggable.js +58 -0
  109. package/dist/useDropZone.d.ts +15 -0
  110. package/dist/useDropZone.js +52 -0
  111. package/dist/useElementBounding.d.ts +21 -0
  112. package/dist/useElementBounding.js +59 -0
  113. package/dist/useElementByPoint.d.ts +10 -0
  114. package/dist/useElementByPoint.js +18 -0
  115. package/dist/useElementHover.d.ts +9 -0
  116. package/dist/useElementHover.js +28 -0
  117. package/dist/useElementSize.d.ts +19 -0
  118. package/dist/useElementSize.js +34 -0
  119. package/dist/useElementVisibility.d.ts +10 -0
  120. package/dist/useElementVisibility.js +10 -0
  121. package/dist/useEventBus.d.ts +14 -0
  122. package/dist/useEventBus.js +41 -0
  123. package/dist/useEventListener.d.ts +14 -0
  124. package/dist/useEventListener.js +29 -0
  125. package/dist/useEventSource.d.ts +32 -0
  126. package/dist/useEventSource.js +72 -0
  127. package/dist/useEyeDropper.d.ts +10 -0
  128. package/dist/useEyeDropper.js +17 -0
  129. package/dist/useFavicon.d.ts +8 -0
  130. package/dist/useFavicon.js +22 -0
  131. package/dist/useFetch.d.ts +35 -0
  132. package/dist/useFetch.js +61 -0
  133. package/dist/useFileDialog.d.ts +15 -0
  134. package/dist/useFileDialog.js +24 -0
  135. package/dist/useFocus.d.ts +13 -0
  136. package/dist/useFocus.js +42 -0
  137. package/dist/useFocusWithin.d.ts +9 -0
  138. package/dist/useFocusWithin.js +29 -0
  139. package/dist/useForm.d.ts +97 -0
  140. package/dist/useForm.js +182 -0
  141. package/dist/useFps.d.ts +7 -0
  142. package/dist/useFps.js +22 -0
  143. package/dist/useFullscreen.d.ts +16 -0
  144. package/dist/useFullscreen.js +67 -0
  145. package/dist/useGeolocation.d.ts +26 -0
  146. package/dist/useGeolocation.js +55 -0
  147. package/dist/useIdle.d.ts +18 -0
  148. package/dist/useIdle.js +46 -0
  149. package/dist/useImage.d.ts +18 -0
  150. package/dist/useImage.js +32 -0
  151. package/dist/useInfiniteScroll.d.ts +11 -0
  152. package/dist/useInfiniteScroll.js +50 -0
  153. package/dist/useIntersectionObserver.d.ts +16 -0
  154. package/dist/useIntersectionObserver.js +27 -0
  155. package/dist/useInterval.d.ts +13 -0
  156. package/dist/useInterval.js +32 -0
  157. package/dist/useIntervalFn.d.ts +16 -0
  158. package/dist/useIntervalFn.js +24 -0
  159. package/dist/useKeyModifier.d.ts +6 -0
  160. package/dist/useKeyModifier.js +22 -0
  161. package/dist/useLastChanged.d.ts +11 -0
  162. package/dist/useLastChanged.js +8 -0
  163. package/dist/useLocalStorage.d.ts +17 -0
  164. package/dist/useLocalStorage.js +4 -0
  165. package/dist/useMagicKeys.d.ts +16 -0
  166. package/dist/useMagicKeys.js +81 -0
  167. package/dist/useManualRefHistory.d.ts +27 -0
  168. package/dist/useManualRefHistory.js +64 -0
  169. package/dist/useMath.d.ts +17 -0
  170. package/dist/useMath.js +52 -0
  171. package/dist/useMediaQuery.d.ts +9 -0
  172. package/dist/useMediaQuery.js +19 -0
  173. package/dist/useMemoize.d.ts +13 -0
  174. package/dist/useMemoize.js +24 -0
  175. package/dist/useMounted.d.ts +6 -0
  176. package/dist/useMounted.js +8 -0
  177. package/dist/useMouse.d.ts +19 -0
  178. package/dist/useMouse.js +67 -0
  179. package/dist/useMouseInElement.d.ts +17 -0
  180. package/dist/useMouseInElement.js +31 -0
  181. package/dist/useMousePressed.d.ts +10 -0
  182. package/dist/useMousePressed.js +31 -0
  183. package/dist/useMutationObserver.d.ts +16 -0
  184. package/dist/useMutationObserver.js +27 -0
  185. package/dist/useNavigatorLanguage.d.ts +5 -0
  186. package/dist/useNavigatorLanguage.js +17 -0
  187. package/dist/useNetwork.d.ts +18 -0
  188. package/dist/useNetwork.js +58 -0
  189. package/dist/useNow.d.ts +8 -0
  190. package/dist/useNow.js +10 -0
  191. package/dist/useObjectUrl.d.ts +8 -0
  192. package/dist/useObjectUrl.js +23 -0
  193. package/dist/useOffsetPagination.d.ts +21 -0
  194. package/dist/useOffsetPagination.js +45 -0
  195. package/dist/useOnline.d.ts +7 -0
  196. package/dist/useOnline.js +20 -0
  197. package/dist/usePageLeave.d.ts +9 -0
  198. package/dist/usePageLeave.js +27 -0
  199. package/dist/useParallax.d.ts +15 -0
  200. package/dist/useParallax.js +33 -0
  201. package/dist/useParentElement.d.ts +6 -0
  202. package/dist/useParentElement.js +8 -0
  203. package/dist/usePermission.d.ts +7 -0
  204. package/dist/usePermission.js +21 -0
  205. package/dist/usePointer.d.ts +15 -0
  206. package/dist/usePointer.js +32 -0
  207. package/dist/usePointerLock.d.ts +13 -0
  208. package/dist/usePointerLock.js +33 -0
  209. package/dist/usePointerSwipe.d.ts +20 -0
  210. package/dist/usePointerSwipe.js +52 -0
  211. package/dist/usePreferredColorScheme.d.ts +6 -0
  212. package/dist/usePreferredColorScheme.js +25 -0
  213. package/dist/usePreferredContrast.d.ts +6 -0
  214. package/dist/usePreferredContrast.js +29 -0
  215. package/dist/usePreferredLanguages.d.ts +5 -0
  216. package/dist/usePreferredLanguages.js +16 -0
  217. package/dist/usePreferredReducedMotion.d.ts +6 -0
  218. package/dist/usePreferredReducedMotion.js +18 -0
  219. package/dist/usePrevious.d.ts +9 -0
  220. package/dist/usePrevious.js +8 -0
  221. package/dist/useQuery.d.ts +106 -0
  222. package/dist/useQuery.js +265 -0
  223. package/dist/useRafFn.d.ts +19 -0
  224. package/dist/useRafFn.js +37 -0
  225. package/dist/useRefHistory.d.ts +28 -0
  226. package/dist/useRefHistory.js +72 -0
  227. package/dist/useResizeObserver.d.ts +16 -0
  228. package/dist/useResizeObserver.js +27 -0
  229. package/dist/useScreenOrientation.d.ts +13 -0
  230. package/dist/useScreenOrientation.js +27 -0
  231. package/dist/useScreenSafeArea.d.ts +12 -0
  232. package/dist/useScreenSafeArea.js +25 -0
  233. package/dist/useScriptTag.d.ts +20 -0
  234. package/dist/useScriptTag.js +52 -0
  235. package/dist/useScroll.d.ts +36 -0
  236. package/dist/useScroll.js +116 -0
  237. package/dist/useScrollLock.d.ts +10 -0
  238. package/dist/useScrollLock.js +39 -0
  239. package/dist/useSessionStorage.d.ts +17 -0
  240. package/dist/useSessionStorage.js +4 -0
  241. package/dist/useShare.d.ts +15 -0
  242. package/dist/useShare.js +11 -0
  243. package/dist/useSorted.d.ts +10 -0
  244. package/dist/useSorted.js +10 -0
  245. package/dist/useStepper.d.ts +23 -0
  246. package/dist/useStepper.js +46 -0
  247. package/dist/useStorage.d.ts +18 -0
  248. package/dist/useStorage.js +54 -0
  249. package/dist/useStyleTag.d.ts +17 -0
  250. package/dist/useStyleTag.js +39 -0
  251. package/dist/useSupported.d.ts +8 -0
  252. package/dist/useSupported.js +10 -0
  253. package/dist/useSwipe.d.ts +20 -0
  254. package/dist/useSwipe.js +58 -0
  255. package/dist/useTextDirection.d.ts +9 -0
  256. package/dist/useTextDirection.js +16 -0
  257. package/dist/useTextSelection.d.ts +10 -0
  258. package/dist/useTextSelection.js +27 -0
  259. package/dist/useTextareaAutosize.d.ts +10 -0
  260. package/dist/useTextareaAutosize.js +20 -0
  261. package/dist/useThrottle.d.ts +9 -0
  262. package/dist/useThrottle.js +23 -0
  263. package/dist/useThrottleFn.d.ts +11 -0
  264. package/dist/useThrottleFn.js +36 -0
  265. package/dist/useThrottledRef.d.ts +11 -0
  266. package/dist/useThrottledRef.js +30 -0
  267. package/dist/useThrottledRefHistory.d.ts +5 -0
  268. package/dist/useThrottledRefHistory.js +43 -0
  269. package/dist/useTimeAgo.d.ts +16 -0
  270. package/dist/useTimeAgo.js +58 -0
  271. package/dist/useTimeout.d.ts +12 -0
  272. package/dist/useTimeout.js +32 -0
  273. package/dist/useTimeoutFn.d.ts +16 -0
  274. package/dist/useTimeoutFn.js +27 -0
  275. package/dist/useTimeoutPoll.d.ts +10 -0
  276. package/dist/useTimeoutPoll.js +33 -0
  277. package/dist/useTimestamp.d.ts +15 -0
  278. package/dist/useTimestamp.js +43 -0
  279. package/dist/useTitle.d.ts +10 -0
  280. package/dist/useTitle.js +12 -0
  281. package/dist/useToNumber.d.ts +11 -0
  282. package/dist/useToNumber.js +25 -0
  283. package/dist/useToString.d.ts +6 -0
  284. package/dist/useToString.js +10 -0
  285. package/dist/useToggle.d.ts +6 -0
  286. package/dist/useToggle.js +12 -0
  287. package/dist/useTransition.d.ts +28 -0
  288. package/dist/useTransition.js +89 -0
  289. package/dist/useUrlSearchParams.d.ts +18 -0
  290. package/dist/useUrlSearchParams.js +72 -0
  291. package/dist/useVibrate.d.ts +13 -0
  292. package/dist/useVibrate.js +14 -0
  293. package/dist/useVirtualList.d.ts +23 -0
  294. package/dist/useVirtualList.js +49 -0
  295. package/dist/useWakeLock.d.ts +12 -0
  296. package/dist/useWakeLock.js +32 -0
  297. package/dist/useWebNotification.d.ts +25 -0
  298. package/dist/useWebNotification.js +39 -0
  299. package/dist/useWebSocket.d.ts +38 -0
  300. package/dist/useWebSocket.js +103 -0
  301. package/dist/useWebWorker.d.ts +18 -0
  302. package/dist/useWebWorker.js +56 -0
  303. package/dist/useWindowFocus.d.ts +5 -0
  304. package/dist/useWindowFocus.js +20 -0
  305. package/dist/useWindowScroll.d.ts +9 -0
  306. package/dist/useWindowScroll.js +17 -0
  307. package/dist/useWindowSize.d.ts +15 -0
  308. package/dist/useWindowSize.js +28 -0
  309. package/dist/watchArray.d.ts +5 -0
  310. package/dist/watchArray.js +9 -0
  311. package/dist/watchAtMost.d.ts +5 -0
  312. package/dist/watchAtMost.js +12 -0
  313. package/dist/watchDebounced.d.ts +23 -0
  314. package/dist/watchDebounced.js +20 -0
  315. package/dist/watchDeep.d.ts +7 -0
  316. package/dist/watchDeep.js +13 -0
  317. package/dist/watchIgnorable.d.ts +12 -0
  318. package/dist/watchIgnorable.js +19 -0
  319. package/dist/watchImmediate.d.ts +5 -0
  320. package/dist/watchImmediate.js +7 -0
  321. package/dist/watchOnce.d.ts +19 -0
  322. package/dist/watchOnce.js +17 -0
  323. package/dist/watchPausable.d.ts +13 -0
  324. package/dist/watchPausable.js +23 -0
  325. package/dist/watchThrottled.d.ts +23 -0
  326. package/dist/watchThrottled.js +37 -0
  327. package/dist/watchTriggerable.d.ts +5 -0
  328. package/dist/watchTriggerable.js +10 -0
  329. package/dist/watchWithFilter.d.ts +7 -0
  330. package/dist/watchWithFilter.js +6 -0
  331. package/dist/whenever.d.ts +18 -0
  332. package/dist/whenever.js +7 -0
  333. package/package.json +2 -2
@@ -0,0 +1,56 @@
1
+ import { onUnmounted, ref } from "@stacksjs/stx";
2
+ export function useWebWorker(url, workerOptions) {
3
+ const data = ref(null), worker = ref(void 0);
4
+ if (typeof Worker < "u") {
5
+ const w = new Worker(url, workerOptions);
6
+ worker.value = w;
7
+ w.onmessage = (e) => {
8
+ data.value = e.data;
9
+ };
10
+ try {
11
+ onUnmounted(() => w.terminate());
12
+ } catch {}
13
+ }
14
+ function post(message) {
15
+ worker.value?.postMessage(message);
16
+ }
17
+ function terminate() {
18
+ worker.value?.terminate();
19
+ worker.value = void 0;
20
+ }
21
+ return { data, post, terminate, worker };
22
+ }
23
+ export function useWebWorkerFn(fn) {
24
+ let worker;
25
+ function createWorker() {
26
+ const blob = new Blob([`self.onmessage = function(e) { self.postMessage((${fn.toString()})(...e.data)); }`], { type: "text/javascript" }), url = URL.createObjectURL(blob);
27
+ return new Worker(url);
28
+ }
29
+ function workerFn(...args) {
30
+ return new Promise((resolve, reject) => {
31
+ if (typeof Worker > "u") {
32
+ try {
33
+ resolve(fn(...args));
34
+ } catch (e) {
35
+ reject(e);
36
+ }
37
+ return;
38
+ }
39
+ worker = createWorker();
40
+ worker.onmessage = (e) => {
41
+ resolve(e.data);
42
+ worker?.terminate();
43
+ };
44
+ worker.onerror = (e) => {
45
+ reject(e);
46
+ worker?.terminate();
47
+ };
48
+ worker.postMessage(args);
49
+ });
50
+ }
51
+ function terminate() {
52
+ worker?.terminate();
53
+ worker = void 0;
54
+ }
55
+ return { workerFn, terminate };
56
+ }
@@ -0,0 +1,5 @@
1
+ import type { Ref } from '@stacksjs/stx';
2
+ /**
3
+ * Reactively track whether the window is focused.
4
+ */
5
+ export declare function useWindowFocus(): Ref<boolean>;
@@ -0,0 +1,20 @@
1
+ import { onUnmounted, ref } from "@stacksjs/stx";
2
+ export function useWindowFocus() {
3
+ const focused = ref(typeof document < "u" ? document.hasFocus() : !1);
4
+ if (typeof window > "u")
5
+ return focused;
6
+ const onFocus = () => {
7
+ focused.value = !0;
8
+ }, onBlur = () => {
9
+ focused.value = !1;
10
+ };
11
+ window.addEventListener("focus", onFocus, { passive: !0 });
12
+ window.addEventListener("blur", onBlur, { passive: !0 });
13
+ try {
14
+ onUnmounted(() => {
15
+ window.removeEventListener("focus", onFocus);
16
+ window.removeEventListener("blur", onBlur);
17
+ });
18
+ } catch {}
19
+ return focused;
20
+ }
@@ -0,0 +1,9 @@
1
+ import type { Ref } from '@stacksjs/stx';
2
+ /**
3
+ * Reactive window scroll position.
4
+ */
5
+ export declare function useWindowScroll(): UseWindowScrollReturn;
6
+ export declare interface UseWindowScrollReturn {
7
+ x: Ref<number>
8
+ y: Ref<number>
9
+ }
@@ -0,0 +1,17 @@
1
+ import { onUnmounted, ref } from "@stacksjs/stx";
2
+ export function useWindowScroll() {
3
+ const x = ref(typeof window < "u" ? window.scrollX : 0), y = ref(typeof window < "u" ? window.scrollY : 0);
4
+ if (typeof window > "u")
5
+ return { x, y };
6
+ const handler = () => {
7
+ x.value = window.scrollX;
8
+ y.value = window.scrollY;
9
+ };
10
+ window.addEventListener("scroll", handler, { passive: !0 });
11
+ try {
12
+ onUnmounted(() => {
13
+ window.removeEventListener("scroll", handler);
14
+ });
15
+ } catch {}
16
+ return { x, y };
17
+ }
@@ -0,0 +1,15 @@
1
+ import type { Ref } from '@stacksjs/stx';
2
+ /**
3
+ * Reactive window dimensions.
4
+ * Tracks window.innerWidth and window.innerHeight.
5
+ */
6
+ export declare function useWindowSize(options?: UseWindowSizeOptions): UseWindowSizeReturn;
7
+ export declare interface UseWindowSizeOptions {
8
+ initialWidth?: number
9
+ initialHeight?: number
10
+ listenOrientation?: boolean
11
+ }
12
+ export declare interface UseWindowSizeReturn {
13
+ width: Ref<number>
14
+ height: Ref<number>
15
+ }
@@ -0,0 +1,28 @@
1
+ import { onUnmounted, ref } from "@stacksjs/stx";
2
+ import { defaultWindow } from "./_shared";
3
+ export function useWindowSize(options) {
4
+ const {
5
+ initialWidth = 0,
6
+ initialHeight = 0,
7
+ listenOrientation = !0
8
+ } = options ?? {}, win = defaultWindow(), width = ref(win ? win.innerWidth : initialWidth), height = ref(win ? win.innerHeight : initialHeight);
9
+ function update() {
10
+ if (win) {
11
+ width.value = win.innerWidth;
12
+ height.value = win.innerHeight;
13
+ }
14
+ }
15
+ if (win) {
16
+ win.addEventListener("resize", update);
17
+ if (listenOrientation)
18
+ win.addEventListener("orientationchange", update);
19
+ try {
20
+ onUnmounted(() => {
21
+ win.removeEventListener("resize", update);
22
+ if (listenOrientation)
23
+ win.removeEventListener("orientationchange", update);
24
+ });
25
+ } catch {}
26
+ }
27
+ return { width, height };
28
+ }
@@ -0,0 +1,5 @@
1
+ import type { Ref } from '@stacksjs/stx';
2
+ /**
3
+ * Watch an array ref and provide added/removed items in the callback.
4
+ */
5
+ export declare function watchArray<T>(source: Ref<T[]>, callback: (newList: T[], oldList: T[], added: T[], removed: T[]) => void): () => void;
@@ -0,0 +1,9 @@
1
+ import { watch } from "@stacksjs/stx";
2
+ export function watchArray(source, callback) {
3
+ let oldList = [...source.value];
4
+ return watch(source, (newValue) => {
5
+ const newList = [...newValue], added = newList.filter((item) => !oldList.includes(item)), removed = oldList.filter((item) => !newList.includes(item));
6
+ callback(newList, oldList, added, removed);
7
+ oldList = newList;
8
+ });
9
+ }
@@ -0,0 +1,5 @@
1
+ import type { Ref } from '@stacksjs/stx';
2
+ /**
3
+ * Watch a source, but only trigger the callback at most `count` times.
4
+ */
5
+ export declare function watchAtMost<T>(source: Ref<T>, callback: (value: T) => void, count: number): { stop: () => void, remaining: Ref<number> };
@@ -0,0 +1,12 @@
1
+ import { ref, watch } from "@stacksjs/stx";
2
+ export function watchAtMost(source, callback, count) {
3
+ const remaining = ref(count), unwatch = watch(source, (newValue) => {
4
+ if (remaining.value > 0) {
5
+ remaining.value--;
6
+ callback(newValue);
7
+ if (remaining.value <= 0)
8
+ unwatch();
9
+ }
10
+ });
11
+ return { stop: unwatch, remaining };
12
+ }
@@ -0,0 +1,23 @@
1
+ import type { Ref } from '@stacksjs/stx';
2
+ /**
3
+ * Watch a source with debounced callback invocation.
4
+ * The callback is only called after the source value has stopped changing
5
+ * for the specified debounce duration.
6
+ *
7
+ * @param source - The reactive source to watch
8
+ * @param callback - The callback to invoke (debounced)
9
+ * @param options - Configuration options
10
+ * @returns A stop function that cleans up both the watch and any pending timer
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * const search = ref('')
15
+ * watchDebounced(search, (value) => {
16
+ * fetchResults(value)
17
+ * }, { debounce: 300 })
18
+ * ```
19
+ */
20
+ export declare function watchDebounced<T>(source: Ref<T>, callback: (value: T) => void, options?: WatchDebouncedOptions): () => void;
21
+ export declare interface WatchDebouncedOptions {
22
+ debounce?: number
23
+ }
@@ -0,0 +1,20 @@
1
+ import { watch } from "@stacksjs/stx";
2
+ export function watchDebounced(source, callback, options) {
3
+ const delay = options?.debounce ?? 200;
4
+ let timeoutId = null;
5
+ const unwatch = watch(source, (newValue) => {
6
+ if (timeoutId !== null)
7
+ clearTimeout(timeoutId);
8
+ timeoutId = setTimeout(() => {
9
+ timeoutId = null;
10
+ callback(newValue);
11
+ }, delay);
12
+ });
13
+ return () => {
14
+ if (timeoutId !== null) {
15
+ clearTimeout(timeoutId);
16
+ timeoutId = null;
17
+ }
18
+ unwatch();
19
+ };
20
+ }
@@ -0,0 +1,7 @@
1
+ import type { Ref } from '@stacksjs/stx';
2
+ /**
3
+ * Watch a source with deep comparison by serializing to JSON.
4
+ * Since stx watch is shallow, this provides deep-watch behavior by
5
+ * comparing JSON serializations.
6
+ */
7
+ export declare function watchDeep<T>(source: Ref<T>, callback: (value: T) => void, options?: { immediate?: boolean }): () => void;
@@ -0,0 +1,13 @@
1
+ import { watch } from "@stacksjs/stx";
2
+ export function watchDeep(source, callback, options) {
3
+ let prev = JSON.stringify(source.value);
4
+ if (options?.immediate)
5
+ callback(source.value);
6
+ return watch(source, (newValue) => {
7
+ const next = JSON.stringify(newValue);
8
+ if (next !== prev) {
9
+ prev = next;
10
+ callback(newValue);
11
+ }
12
+ });
13
+ }
@@ -0,0 +1,12 @@
1
+ import type { Ref } from '@stacksjs/stx';
2
+ /**
3
+ * A watch that can temporarily ignore updates.
4
+ */
5
+ export declare function watchIgnorable<T>(source: Ref<T>, callback: (value: T, oldValue: T | undefined) => void): WatchIgnorableReturn;
6
+ /** Alias for watchIgnorable */
7
+ export declare const ignorableWatch: unknown;
8
+ export declare interface WatchIgnorableReturn {
9
+ stop: () => void
10
+ ignoreUpdates: (updater: () => void) => void
11
+ isIgnoring: Ref<boolean>
12
+ }
@@ -0,0 +1,19 @@
1
+ import { ref, watch } from "@stacksjs/stx";
2
+ export function watchIgnorable(source, callback) {
3
+ const isIgnoring = ref(!1);
4
+ let lastValue;
5
+ const unwatch = watch(source, (newValue) => {
6
+ if (!isIgnoring.value)
7
+ callback(newValue, lastValue);
8
+ lastValue = newValue;
9
+ });
10
+ function ignoreUpdates(updater) {
11
+ isIgnoring.value = !0;
12
+ updater();
13
+ Promise.resolve().then(() => {
14
+ isIgnoring.value = !1;
15
+ });
16
+ }
17
+ return { stop: unwatch, ignoreUpdates, isIgnoring };
18
+ }
19
+ export const ignorableWatch = watchIgnorable;
@@ -0,0 +1,5 @@
1
+ import type { Ref } from '@stacksjs/stx';
2
+ /**
3
+ * Watch a source and call the callback immediately with the current value, then on changes.
4
+ */
5
+ export declare function watchImmediate<T>(source: Ref<T>, callback: (value: T) => void): () => void;
@@ -0,0 +1,7 @@
1
+ import { watch } from "@stacksjs/stx";
2
+ export function watchImmediate(source, callback) {
3
+ callback(source.value);
4
+ return watch(source, (newValue) => {
5
+ callback(newValue);
6
+ });
7
+ }
@@ -0,0 +1,19 @@
1
+ import type { Ref } from '@stacksjs/stx';
2
+ /**
3
+ * Watch a source and automatically stop after the first change.
4
+ *
5
+ * @param source - The reactive source to watch
6
+ * @param callback - The callback to invoke on the first change
7
+ * @returns A manual stop function (in case you want to stop before first trigger)
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * const count = ref(0)
12
+ * watchOnce(count, (value) => {
13
+ * console.log('First change:', value)
14
+ * })
15
+ * count.value = 1 // callback fires
16
+ * count.value = 2 // callback does NOT fire
17
+ * ```
18
+ */
19
+ export declare function watchOnce<T>(source: Ref<T>, callback: (value: T) => void): () => void;
@@ -0,0 +1,17 @@
1
+ import { watch } from "@stacksjs/stx";
2
+ export function watchOnce(source, callback) {
3
+ let stopped = !1;
4
+ const unwatch = watch(source, (newValue) => {
5
+ if (stopped)
6
+ return;
7
+ stopped = !0;
8
+ unwatch();
9
+ callback(newValue);
10
+ });
11
+ return () => {
12
+ if (!stopped) {
13
+ stopped = !0;
14
+ unwatch();
15
+ }
16
+ };
17
+ }
@@ -0,0 +1,13 @@
1
+ import type { Ref } from '@stacksjs/stx';
2
+ /**
3
+ * A pausable watch.
4
+ */
5
+ export declare function watchPausable<T>(source: Ref<T>, callback: (value: T, oldValue: T | undefined) => void): WatchPausableReturn;
6
+ /** Alias for watchPausable */
7
+ export declare const pausableWatch: unknown;
8
+ export declare interface WatchPausableReturn {
9
+ stop: () => void
10
+ pause: () => void
11
+ resume: () => void
12
+ isActive: Ref<boolean>
13
+ }
@@ -0,0 +1,23 @@
1
+ import { ref, watch } from "@stacksjs/stx";
2
+ export function watchPausable(source, callback) {
3
+ const isActive = ref(!0);
4
+ let lastValue;
5
+ const unwatch = watch(source, (newValue) => {
6
+ if (isActive.value)
7
+ callback(newValue, lastValue);
8
+ lastValue = newValue;
9
+ });
10
+ function pause() {
11
+ isActive.value = !1;
12
+ }
13
+ function resume() {
14
+ isActive.value = !0;
15
+ }
16
+ return {
17
+ stop: unwatch,
18
+ pause,
19
+ resume,
20
+ isActive
21
+ };
22
+ }
23
+ export const pausableWatch = watchPausable;
@@ -0,0 +1,23 @@
1
+ import type { Ref } from '@stacksjs/stx';
2
+ /**
3
+ * Watch a source with throttled callback invocation.
4
+ * The callback is called at most once per throttle interval.
5
+ * A trailing call is scheduled if changes occur during the throttle window.
6
+ *
7
+ * @param source - The reactive source to watch
8
+ * @param callback - The callback to invoke (throttled)
9
+ * @param options - Configuration options
10
+ * @returns A stop function that cleans up both the watch and any pending timer
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * const scrollY = ref(0)
15
+ * watchThrottled(scrollY, (value) => {
16
+ * updateHeader(value)
17
+ * }, { throttle: 100 })
18
+ * ```
19
+ */
20
+ export declare function watchThrottled<T>(source: Ref<T>, callback: (value: T) => void, options?: WatchThrottledOptions): () => void;
21
+ export declare interface WatchThrottledOptions {
22
+ throttle?: number
23
+ }
@@ -0,0 +1,37 @@
1
+ import { watch } from "@stacksjs/stx";
2
+ export function watchThrottled(source, callback, options) {
3
+ const interval = options?.throttle ?? 200;
4
+ let lastExec = 0, timeoutId = null, latestValue, hasPending = !1;
5
+ const unwatch = watch(source, (newValue) => {
6
+ const now = Date.now(), elapsed = now - lastExec;
7
+ if (elapsed >= interval) {
8
+ lastExec = now;
9
+ if (timeoutId !== null) {
10
+ clearTimeout(timeoutId);
11
+ timeoutId = null;
12
+ }
13
+ hasPending = !1;
14
+ callback(newValue);
15
+ } else {
16
+ latestValue = newValue;
17
+ hasPending = !0;
18
+ if (timeoutId === null)
19
+ timeoutId = setTimeout(() => {
20
+ lastExec = Date.now();
21
+ timeoutId = null;
22
+ if (hasPending) {
23
+ hasPending = !1;
24
+ callback(latestValue);
25
+ }
26
+ }, interval - elapsed);
27
+ }
28
+ });
29
+ return () => {
30
+ if (timeoutId !== null) {
31
+ clearTimeout(timeoutId);
32
+ timeoutId = null;
33
+ }
34
+ hasPending = !1;
35
+ unwatch();
36
+ };
37
+ }
@@ -0,0 +1,5 @@
1
+ import type { Ref } from '@stacksjs/stx';
2
+ /**
3
+ * A watch that can also be manually triggered.
4
+ */
5
+ export declare function watchTriggerable<T>(source: Ref<T>, callback: (value: T) => void): { stop: () => void, trigger: () => void };
@@ -0,0 +1,10 @@
1
+ import { watch } from "@stacksjs/stx";
2
+ export function watchTriggerable(source, callback) {
3
+ const unwatch = watch(source, (newValue) => {
4
+ callback(newValue);
5
+ });
6
+ function trigger() {
7
+ callback(source.value);
8
+ }
9
+ return { stop: unwatch, trigger };
10
+ }
@@ -0,0 +1,7 @@
1
+ import type { Ref } from '@stacksjs/stx';
2
+ /**
3
+ * Watch a source with a custom event filter.
4
+ * The filter receives the invoke function and decides when to call it.
5
+ */
6
+ export declare function watchWithFilter<T>(source: Ref<T>, callback: (value: T) => void, eventFilter: EventFilter): () => void;
7
+ export type EventFilter = (invoke: () => void) => void;
@@ -0,0 +1,6 @@
1
+ import { watch } from "@stacksjs/stx";
2
+ export function watchWithFilter(source, callback, eventFilter) {
3
+ return watch(source, (newValue) => {
4
+ eventFilter(() => callback(newValue));
5
+ });
6
+ }
@@ -0,0 +1,18 @@
1
+ import type { Ref } from '@stacksjs/stx';
2
+ /**
3
+ * Watch a source and call callback only when the value becomes truthy.
4
+ *
5
+ * @param source - The reactive source to watch
6
+ * @param callback - The callback to invoke when the source value is truthy
7
+ * @returns An unsubscribe function that stops watching
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * const isReady = ref(false)
12
+ * whenever(isReady, (value) => {
13
+ * console.log('Ready!', value)
14
+ * })
15
+ * isReady.value = true // callback fires
16
+ * ```
17
+ */
18
+ export declare function whenever<T>(source: Ref<T>, callback: (value: T) => void): () => void;
@@ -0,0 +1,7 @@
1
+ import { watch } from "@stacksjs/stx";
2
+ export function whenever(source, callback) {
3
+ return watch(source, (newValue) => {
4
+ if (newValue)
5
+ callback(newValue);
6
+ });
7
+ }
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@stacksjs/composables",
3
3
  "type": "module",
4
4
  "sideEffects": false,
5
- "version": "0.70.87",
5
+ "version": "0.70.90",
6
6
  "description": "Stacks composables powered by stx reactivity.",
7
7
  "author": "Chris Breuer",
8
8
  "contributors": [
@@ -53,7 +53,7 @@
53
53
  },
54
54
  "dependencies": {
55
55
  "@stacksjs/stx": "^0.2.82",
56
- "@stacksjs/datetime": "0.70.87"
56
+ "@stacksjs/datetime": "0.70.90"
57
57
  },
58
58
  "devDependencies": {
59
59
  "better-dx": "^0.2.16"