Skip to content

Commit cacab35

Browse files
committed
Add and document {Async,}Callback.debounce
See #967 for motivation
1 parent b02d8e9 commit cacab35

File tree

7 files changed

+147
-0
lines changed

7 files changed

+147
-0
lines changed

callback/src/main/scala-2/japgolly/scalajs/react/callback/AsyncCallback.scala

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,27 @@ object AsyncCallback {
299299
}
300300
}
301301

302+
/** Creates an debounce boundary.
303+
*
304+
* Save it as a `val` somewhere because it relies on internal state that must be reused.
305+
*/
306+
@inline def debounce(delay: Duration): AsyncCallback[Unit] =
307+
unit.debounce(delay)
308+
309+
/** Creates an debounce boundary.
310+
*
311+
* Save it as a `val` somewhere because it relies on internal state that must be reused.
312+
*/
313+
@inline def debounce(delay: FiniteDuration): AsyncCallback[Unit] =
314+
unit.debounce(delay)
315+
316+
/** Creates an debounce boundary.
317+
*
318+
* Save it as a `val` somewhere because it relies on internal state that must be reused.
319+
*/
320+
@inline def debounceMs(delayMs: Long): AsyncCallback[Unit] =
321+
unit.debounceMs(delayMs)
322+
302323
def awaitAll(as: AsyncCallback[Any]*): AsyncCallback[Unit] =
303324
if (as.isEmpty)
304325
unit
@@ -864,12 +885,24 @@ final class AsyncCallback[+A] private[AsyncCallback] (val underlyingRepr: AsyncC
864885
}
865886
}
866887

888+
/** Creates an debounce boundary over the underlying computation.
889+
*
890+
* Save the result of this as a `val` somewhere because it relies on internal state that must be reused.
891+
*/
867892
def debounce(delay: Duration): AsyncCallback[A] =
868893
debounceMs(delay.toMillis)
869894

895+
/** Creates an debounce boundary over the underlying computation.
896+
*
897+
* Save the result of this as a `val` somewhere because it relies on internal state that must be reused.
898+
*/
870899
def debounce(delay: FiniteDuration): AsyncCallback[A] =
871900
debounceMs(delay.toMillis)
872901

902+
/** Creates an debounce boundary over the underlying computation.
903+
*
904+
* Save the result of this as a `val` somewhere because it relies on internal state that must be reused.
905+
*/
873906
def debounceMs(delayMs: Long): AsyncCallback[A] =
874907
AsyncCallback.debounce(delayMs, this)
875908

callback/src/main/scala-2/japgolly/scalajs/react/callback/Callback.scala

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package japgolly.scalajs.react.callback
22

33
import japgolly.scalajs.react.util.Util.identityFn
4+
import java.time.Duration
45
import org.scalajs.dom.{console, window}
56
import scala.annotation.implicitNotFound
7+
import scala.concurrent.duration.FiniteDuration
68
import scala.concurrent.{ExecutionContext, Future}
79
import scala.scalajs.js
810
import scala.scalajs.js.timers.{RawTimers, SetIntervalHandle, SetTimeoutHandle}
@@ -124,6 +126,27 @@ object Callback {
124126
def sequenceOption[A](oca: => Option[CallbackTo[A]]): Callback =
125127
traverseOption(oca)(identityFn)
126128

129+
/** Creates an debounce boundary.
130+
*
131+
* Save it as a `val` somewhere because it relies on internal state that must be reused.
132+
*/
133+
@inline def debounce(delay: Duration): Callback =
134+
empty.debounce(delay)
135+
136+
/** Creates an debounce boundary.
137+
*
138+
* Save it as a `val` somewhere because it relies on internal state that must be reused.
139+
*/
140+
@inline def debounce(delay: FiniteDuration): Callback =
141+
empty.debounce(delay)
142+
143+
/** Creates an debounce boundary.
144+
*
145+
* Save it as a `val` somewhere because it relies on internal state that must be reused.
146+
*/
147+
@inline def debounceMs(delayMs: Long): Callback =
148+
empty.debounceMs(delayMs)
149+
127150
/** Run all given callbacks.
128151
*
129152
* All results are discarded.

callback/src/main/scala-2/japgolly/scalajs/react/callback/CallbackTo.scala

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,12 +486,24 @@ final class CallbackTo[+A] private[react] (private[CallbackTo] val trampoline: T
486486
windowMs = windowMs,
487487
))
488488

489+
/** Creates an debounce boundary over the underlying computation.
490+
*
491+
* Save the result of this as a `val` somewhere because it relies on internal state that must be reused.
492+
*/
489493
def debounce(delay: Duration): Callback =
490494
_debounceMs(delay.toMillis)
491495

496+
/** Creates an debounce boundary over the underlying computation.
497+
*
498+
* Save the result of this as a `val` somewhere because it relies on internal state that must be reused.
499+
*/
492500
def debounce(delay: FiniteDuration): Callback =
493501
_debounceMs(delay.toMillis)
494502

503+
/** Creates an debounce boundary over the underlying computation.
504+
*
505+
* Save the result of this as a `val` somewhere because it relies on internal state that must be reused.
506+
*/
495507
def debounceMs(delayMs: Long): Callback =
496508
_debounceMs(delayMs)
497509

callback/src/main/scala-3/japgolly/scalajs/react/callback/AsyncCallback.scala

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,28 @@ object AsyncCallback {
300300
}
301301
}
302302

303+
304+
/** Creates an debounce boundary.
305+
*
306+
* Save it as a `val` somewhere because it relies on internal state that must be reused.
307+
*/
308+
inline def debounce(delay: Duration): AsyncCallback[Unit] =
309+
unit.debounce(delay)
310+
311+
/** Creates an debounce boundary.
312+
*
313+
* Save it as a `val` somewhere because it relies on internal state that must be reused.
314+
*/
315+
inline def debounce(delay: FiniteDuration): AsyncCallback[Unit] =
316+
unit.debounce(delay)
317+
318+
/** Creates an debounce boundary.
319+
*
320+
* Save it as a `val` somewhere because it relies on internal state that must be reused.
321+
*/
322+
inline def debounceMs(delayMs: Long): AsyncCallback[Unit] =
323+
unit.debounceMs(delayMs)
324+
303325
def awaitAll(as: AsyncCallback[Any]*): AsyncCallback[Unit] =
304326
if (as.isEmpty)
305327
unit
@@ -874,12 +896,24 @@ final class AsyncCallback[+A] private[AsyncCallback] (val underlyingRepr: AsyncC
874896
}
875897
}
876898

899+
/** Creates an debounce boundary over the underlying computation.
900+
*
901+
* Save the result of this as a `val` somewhere because it relies on internal state that must be reused.
902+
*/
877903
inline def debounce(inline delay: Duration): AsyncCallback[A] =
878904
debounceMs(delay.toMillis)
879905

906+
/** Creates an debounce boundary over the underlying computation.
907+
*
908+
* Save the result of this as a `val` somewhere because it relies on internal state that must be reused.
909+
*/
880910
inline def debounce(inline delay: FiniteDuration): AsyncCallback[A] =
881911
debounceMs(delay.toMillis)
882912

913+
/** Creates an debounce boundary over the underlying computation.
914+
*
915+
* Save the result of this as a `val` somewhere because it relies on internal state that must be reused.
916+
*/
883917
def debounceMs(delayMs: Long): AsyncCallback[A] =
884918
AsyncCallback.debounce(delayMs, this)
885919

callback/src/main/scala-3/japgolly/scalajs/react/callback/Callback.scala

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package japgolly.scalajs.react.callback
22

33
import japgolly.scalajs.react.util.Util.identityFn
4+
import java.time.Duration
45
import org.scalajs.dom.{console, window}
56
import scala.annotation.implicitNotFound
7+
import scala.concurrent.duration.FiniteDuration
68
import scala.concurrent.{ExecutionContext, Future}
79
import scala.language.`3.0`
810
import scala.scalajs.js
@@ -125,6 +127,27 @@ object Callback {
125127
inline def sequenceOption[A](inline oca: Option[CallbackTo[A]]): Callback =
126128
traverseOption(oca)(identityFn)
127129

130+
/** Creates an debounce boundary.
131+
*
132+
* Save it as a `val` somewhere because it relies on internal state that must be reused.
133+
*/
134+
inline def debounce(delay: Duration): Callback =
135+
empty.debounce(delay)
136+
137+
/** Creates an debounce boundary.
138+
*
139+
* Save it as a `val` somewhere because it relies on internal state that must be reused.
140+
*/
141+
inline def debounce(delay: FiniteDuration): Callback =
142+
empty.debounce(delay)
143+
144+
/** Creates an debounce boundary.
145+
*
146+
* Save it as a `val` somewhere because it relies on internal state that must be reused.
147+
*/
148+
inline def debounceMs(delayMs: Long): Callback =
149+
empty.debounceMs(delayMs)
150+
128151
/** Run all given callbacks.
129152
*
130153
* All results are discarded.

callback/src/main/scala-3/japgolly/scalajs/react/callback/CallbackTo.scala

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,12 +524,24 @@ final class CallbackTo[+A] /*private[react]*/ (private[CallbackTo] val trampolin
524524
windowMs = windowMs,
525525
))
526526

527+
/** Creates an debounce boundary over the underlying computation.
528+
*
529+
* Save the result of this as a `val` somewhere because it relies on internal state that must be reused.
530+
*/
527531
inline def debounce(inline delay: Duration): Callback =
528532
__debounceMs(delay.toMillis)
529533

534+
/** Creates an debounce boundary over the underlying computation.
535+
*
536+
* Save the result of this as a `val` somewhere because it relies on internal state that must be reused.
537+
*/
530538
inline def debounce(inline delay: FiniteDuration): Callback =
531539
__debounceMs(delay.toMillis)
532540

541+
/** Creates an debounce boundary over the underlying computation.
542+
*
543+
* Save the result of this as a `val` somewhere because it relies on internal state that must be reused.
544+
*/
533545
inline def debounceMs(inline delayMs: Long): Callback =
534546
__debounceMs(delayMs)
535547

doc/changelog/2.0.0.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,16 @@ You can run the script in the Migration section at the bottom of the page to aut
351351
* UnivEq to 1.6.0
352352
353353
354+
# Changes in RC4
355+
356+
* Document existing `debounce` methods to clarify you need to save them as a `val` and reuse them
357+
* Add:
358+
* `AsyncCallback.debounce(duration): AsyncCallback[Unit]`
359+
* `Callback.debounce(duration): Callback`
360+
* Upgrade deps
361+
* Cats-effect to 3.2.3
362+
363+
354364
# Thanks
355365
356366
A lot of this was kindly sponsored by [Gemini](https://www.gemini.edu/)/[NOIRLab](https://nationalastro.org/)/[AURA](https://www.aura-astronomy.org/).

0 commit comments

Comments
 (0)