@@ -15,21 +15,29 @@ type EventAsReturnType<Payload> = any extends Payload ? Event<Payload> : never;
1515export function throttle < T > ( _ : {
1616 source : Unit < T > ;
1717 timeout : number | Store < number > ;
18+ leading ?: boolean | Store < boolean > ;
19+ trailing ?: boolean | Store < boolean > ;
1820 name ?: string ;
1921} ) : EventAsReturnType < T > ;
2022export function throttle < T , Target extends Unit < T > > ( _ : {
2123 source : Unit < T > ;
2224 timeout : number | Store < number > ;
2325 target : Target ;
26+ leading ?: boolean | Store < boolean > ;
27+ trailing ?: boolean | Store < boolean > ;
2428 name ?: string ;
2529} ) : Target ;
2630export function throttle < T > ( {
2731 source,
2832 timeout,
33+ leading,
34+ trailing,
2935 target = createEvent < T > ( ) ,
3036} : {
3137 source : Unit < T > ;
3238 timeout : number | Store < number > ;
39+ leading ?: boolean | Store < boolean > ;
40+ trailing ?: boolean | Store < boolean > ;
3341 name ?: string ;
3442 target ?: Unit < any > ;
3543} ) : EventAsReturnType < T > {
@@ -42,13 +50,18 @@ export function throttle<T>({
4250 ) ;
4351
4452 // It's ok - nothing will ever start unless source is triggered
45- const $payload = createStore < T > ( null as unknown as T , { serialize : 'ignore' } ) . on (
46- source ,
47- ( _ , payload ) => payload ,
48- ) ;
53+ const $payload = createStore < T > ( null as unknown as T , {
54+ serialize : 'ignore' ,
55+ } ) . on ( source , ( _ , payload ) => payload ) ;
4956
5057 const triggerTick = createEvent < T > ( ) ;
5158
59+ const $leading = toStoreBoolean ( leading , '$leading' , false ) ;
60+ const $trailing = toStoreBoolean ( trailing , '$trailing' , true ) ;
61+
62+ const $neverCalled = createStore ( true ) . on ( target , ( ) => false ) ;
63+ const $lastCalled = createStore < number > ( 0 ) . on ( target , ( ) => Date . now ( ) ) ;
64+
5265 const $canTick = createStore ( true , { serialize : 'ignore' } )
5366 . on ( triggerTick , ( ) => false )
5467 . on ( target , ( ) => true ) ;
@@ -66,8 +79,25 @@ export function throttle<T>({
6679 } ) ;
6780
6881 sample ( {
69- source : $payload ,
82+ clock : $payload ,
83+ source : [ $leading , $neverCalled ] ,
84+ filter : ( [ leading , neverCalled ] ) => leading && neverCalled ,
85+ target,
86+ } ) ;
87+
88+ sample ( {
89+ source : [ $trailing , $payload ] as const ,
7090 clock : timerFx . done ,
91+ filter : ( [ trailing ] ) => trailing ,
92+ fn : ( [ _ , payload ] ) => payload ,
93+ target,
94+ } ) ;
95+ sample ( {
96+ clock : $payload ,
97+ source : { trailing : $trailing , lastCalled : $lastCalled , timeout : $timeout } ,
98+ filter : ( { trailing, lastCalled, timeout } ) =>
99+ ! trailing && lastCalled + timeout < Date . now ( ) ,
100+ fn : ( _src , clk ) => clk ,
71101 target,
72102 } ) ;
73103
@@ -88,3 +118,16 @@ function toStoreNumber(value: number | Store<number> | unknown): Store<number> {
88118 `timeout parameter should be number or Store. "${ typeof value } " was passed` ,
89119 ) ;
90120}
121+
122+ function toStoreBoolean (
123+ value : boolean | Store < boolean > | undefined ,
124+ name : string ,
125+ defaultValue : boolean ,
126+ ) : Store < boolean > {
127+ if ( is . store ( value ) ) return value ;
128+ if ( typeof value === 'boolean' ) {
129+ return createStore ( value , { name } ) ;
130+ } else {
131+ return createStore ( defaultValue , { name } ) ;
132+ }
133+ }
0 commit comments