11import { useState , useRef } from "atomico" ;
2+
3+ const fpsP = ( ) =>
4+ new Promise ( ( resolve ) => requestAnimationFrame ( ( ) => resolve ( ) ) ) ;
5+
6+ /**
7+ * Transform a fps into a promise
8+ * @param {number } length
9+ */
10+ export const fps = async ( length = 1 ) => {
11+ let current = Promise . resolve ( ) ;
12+
13+ while ( length -- ) current = current . then ( fpsP ) ;
14+
15+ await current ;
16+ } ;
17+
18+ /**
19+ *
20+ * @param {number } ms
21+ * @returns {Promise<void> }
22+ */
23+ export const idle = ( ms ) =>
24+ window . requestIdleCallback
25+ ? new Promise ( ( resolve ) => requestIdleCallback ( resolve , { ms : timeout } ) )
26+ : timeout ( ms ) ;
27+
28+ /**
29+ *
30+ * @param {number } ms
31+ * @returns {Promise<void> }
32+ */
33+ export const timeout = ( ms ) =>
34+ new Promise ( ( resolve ) => setTimeout ( resolve , ms ) ) ;
35+
236/**
337 * Generates a bottleneck in the definition of the state
438 * @template T
539 * @param {number } delay
640 * @param {T } [initialState]
41+ * @param {"timeout"|"fps"|"idle" } [mode]
742 * @return {[T extends (...args:any[])=>infer R ? R : T, (current: T extends (...args:any[])=>infer R ? R : T)=>void] }
843 */
9- export function useDebounceState ( delay , initialState ) {
44+ export function useDebounceState ( delay , initialState , mode = "timeout" ) {
1045 const [ state , setState ] = useState ( initialState ) ;
1146 const ref = useRef ( ) ;
1247 return [
@@ -15,10 +50,12 @@ export function useDebounceState(delay, initialState) {
1550 ref . current = current ;
1651 if ( ! ref . prevent ) {
1752 ref . prevent = true ;
18- setTimeout ( ( ) => {
19- ref . prevent = false ;
20- setState ( ref . current ) ;
21- } , delay ) ;
53+ ( mode === "fps" ? fps : mode === "idle" ? idle : timeout ) ( delay ) . then (
54+ ( ) => {
55+ ref . prevent = false ;
56+ setState ( ref . current ) ;
57+ }
58+ ) ;
2259 }
2360 } ,
2461 ] ;
0 commit comments