@oscarpalmer/atoms 0.150.0 → 0.152.0
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.
- package/dist/atoms.full.js +51 -80
- package/dist/function/index.js +24 -0
- package/dist/index.js +2 -4
- package/dist/internal/function/timer.js +31 -0
- package/dist/promise/delay.js +6 -9
- package/dist/promise/timed.js +7 -10
- package/package.json +2 -18
- package/src/function/index.ts +41 -0
- package/src/index.ts +1 -7
- package/src/internal/function/timer.ts +68 -0
- package/src/promise/delay.ts +9 -12
- package/src/promise/timed.ts +11 -14
- package/types/function/{debounce.d.ts → index.d.ts} +9 -0
- package/types/index.d.ts +1 -5
- package/types/internal/function/timer.d.ts +7 -0
- package/dist/function/debounce.js +0 -13
- package/dist/function/misc.js +0 -2
- package/dist/function/throttle.js +0 -11
- package/dist/internal/frame-rate.js +0 -25
- package/dist/internal/function/limiter.js +0 -29
- package/src/function/debounce.ts +0 -21
- package/src/function/misc.ts +0 -1
- package/src/function/throttle.ts +0 -19
- package/src/internal/frame-rate.ts +0 -63
- package/src/internal/function/limiter.ts +0 -52
- package/types/function/misc.d.ts +0 -1
- package/types/function/throttle.d.ts +0 -8
- package/types/internal/frame-rate.d.ts +0 -2
- package/types/internal/function/limiter.d.ts +0 -3
package/dist/atoms.full.js
CHANGED
|
@@ -1,27 +1,3 @@
|
|
|
1
|
-
function calculate() {
|
|
2
|
-
return new Promise((resolve) => {
|
|
3
|
-
const values = [];
|
|
4
|
-
let last;
|
|
5
|
-
function step(now) {
|
|
6
|
-
if (last != null) values.push(now - last);
|
|
7
|
-
last = now;
|
|
8
|
-
if (values.length >= TOTAL) resolve(values.sort().slice(TRIM_PART, -TRIM_PART).reduce((first, second) => first + second, 0) / (values.length - TRIM_TOTAL));
|
|
9
|
-
else requestAnimationFrame(step);
|
|
10
|
-
}
|
|
11
|
-
requestAnimationFrame(step);
|
|
12
|
-
});
|
|
13
|
-
}
|
|
14
|
-
const TOTAL = 10;
|
|
15
|
-
const TRIM_PART = 2;
|
|
16
|
-
const TRIM_TOTAL = 4;
|
|
17
|
-
let FRAME_RATE_MS = 1e3 / 60;
|
|
18
|
-
/**
|
|
19
|
-
* A calculated average of the refresh rate of the display _(in milliseconds)_
|
|
20
|
-
*/
|
|
21
|
-
calculate().then((value) => {
|
|
22
|
-
FRAME_RATE_MS = value;
|
|
23
|
-
});
|
|
24
|
-
var frame_rate_default = FRAME_RATE_MS;
|
|
25
1
|
function getArrayCallback(value) {
|
|
26
2
|
switch (typeof value) {
|
|
27
3
|
case "function": return value;
|
|
@@ -701,44 +677,40 @@ function unique(array, key) {
|
|
|
701
677
|
if (!Array.isArray(array)) return [];
|
|
702
678
|
return array.length > 1 ? findValues("unique", array, [key, void 0]).matched : array;
|
|
703
679
|
}
|
|
704
|
-
function
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
680
|
+
function getInterval(value) {
|
|
681
|
+
return typeof value === "number" && value > 0 ? value : 0;
|
|
682
|
+
}
|
|
683
|
+
function getTimer(type, callback, time) {
|
|
684
|
+
const interval = getInterval(time);
|
|
685
|
+
function run(now) {
|
|
686
|
+
start ??= now;
|
|
687
|
+
if (interval === 0 || now - start >= interval - OFFSET) {
|
|
688
|
+
if (throttle) start = now;
|
|
689
|
+
callback(...args);
|
|
690
|
+
} else frame = requestAnimationFrame(run);
|
|
713
691
|
}
|
|
692
|
+
const throttle = type === TIMER_THROTTLE;
|
|
693
|
+
let args;
|
|
714
694
|
let frame;
|
|
715
|
-
let
|
|
716
|
-
const
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
step(now, parameters);
|
|
721
|
-
});
|
|
695
|
+
let start;
|
|
696
|
+
const timer = (...parameters) => {
|
|
697
|
+
timer.cancel();
|
|
698
|
+
args = parameters;
|
|
699
|
+
frame = requestAnimationFrame(run);
|
|
722
700
|
};
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
cancelAnimationFrame(frame);
|
|
726
|
-
frame = void 0;
|
|
727
|
-
}
|
|
701
|
+
timer.cancel = () => {
|
|
702
|
+
cancelAnimationFrame(frame);
|
|
728
703
|
};
|
|
729
|
-
return
|
|
704
|
+
return timer;
|
|
730
705
|
}
|
|
706
|
+
const OFFSET = 5;
|
|
707
|
+
const TIMER_DEBOUNCE = "debounce";
|
|
708
|
+
const TIMER_THROTTLE = "throttle";
|
|
709
|
+
const TIMER_WAIT = "wait";
|
|
731
710
|
/**
|
|
732
|
-
*
|
|
733
|
-
*
|
|
734
|
-
* On subsequent calls, the timer is reset and will wait another `time` milliseconds _(and so on...)_
|
|
735
|
-
* @param callback Callback to debounce
|
|
736
|
-
* @param time Time in milliseconds to wait before calling the callback _(defaults to match frame rate)_
|
|
737
|
-
* @returns Debounced callback with a `cancel` method
|
|
711
|
+
* A function that does nothing, which can be useful, I guess…
|
|
738
712
|
*/
|
|
739
|
-
function
|
|
740
|
-
return getLimiter(callback, false, time);
|
|
741
|
-
}
|
|
713
|
+
function noop() {}
|
|
742
714
|
/**
|
|
743
715
|
* Is the number between a minimum and maximum value?
|
|
744
716
|
* @param value Value to check
|
|
@@ -946,13 +918,24 @@ function memoize(callback, options) {
|
|
|
946
918
|
}
|
|
947
919
|
const DEFAULT_CACHE_SIZE = 1024;
|
|
948
920
|
/**
|
|
921
|
+
* Debounce a function, ensuring it is only called after `time` milliseconds have passed
|
|
922
|
+
*
|
|
923
|
+
* On subsequent calls, the timer is reset and will wait another `time` milliseconds _(and so on...)_
|
|
924
|
+
* @param callback Callback to debounce
|
|
925
|
+
* @param time Time in milliseconds to wait before calling the callback _(defaults to match frame rate)_
|
|
926
|
+
* @returns Debounced callback with a `cancel` method
|
|
927
|
+
*/
|
|
928
|
+
function debounce(callback, time) {
|
|
929
|
+
return getTimer(TIMER_DEBOUNCE, callback, time);
|
|
930
|
+
}
|
|
931
|
+
/**
|
|
949
932
|
* Throttle a function, ensuring it is only called once every `time` milliseconds
|
|
950
933
|
* @param callback Callback to throttle
|
|
951
934
|
* @param time Time in milliseconds to wait before calling the callback again _(defaults to match frame rate)_
|
|
952
935
|
* @returns Throttled callback with a `cancel` method
|
|
953
936
|
*/
|
|
954
937
|
function throttle(callback, time) {
|
|
955
|
-
return
|
|
938
|
+
return getTimer(TIMER_THROTTLE, callback, time);
|
|
956
939
|
}
|
|
957
940
|
function _isResult(value, okValue) {
|
|
958
941
|
if (!isPlainObject(value)) return false;
|
|
@@ -1053,10 +1036,6 @@ const MESSAGE_PIPE_ARRAY = "Pipe expected to receive an array of functions";
|
|
|
1053
1036
|
const MESSAGE_PIPE_PROMISE = "Synchronous Pipe received a promise. Use `pipe.async` instead.";
|
|
1054
1037
|
const assertFlowFunctions = assert.condition((value) => Array.isArray(value) && value.every((item) => typeof item === "function"), MESSAGE_FLOW_ARRAY, TypeError);
|
|
1055
1038
|
const assertPipeFunctions = assert.condition((value) => Array.isArray(value) && value.every((item) => typeof item === "function"), MESSAGE_PIPE_ARRAY, TypeError);
|
|
1056
|
-
/**
|
|
1057
|
-
* A function that does nothing, which can be useful, I guess…
|
|
1058
|
-
*/
|
|
1059
|
-
function noop() {}
|
|
1060
1039
|
function equal(first, second, options) {
|
|
1061
1040
|
return equalValue(first, second, getEqualOptions(options));
|
|
1062
1041
|
}
|
|
@@ -3147,23 +3126,19 @@ async function toResult(value) {
|
|
|
3147
3126
|
}
|
|
3148
3127
|
async function getTimedPromise(promise, time, signal) {
|
|
3149
3128
|
function abort() {
|
|
3150
|
-
|
|
3129
|
+
timer.cancel();
|
|
3151
3130
|
rejector(signal.reason);
|
|
3152
3131
|
}
|
|
3153
|
-
function run(now) {
|
|
3154
|
-
start ??= now;
|
|
3155
|
-
if (time === 0 || now - start >= time - 5) settlePromise(abort, rejector, new PromiseTimeoutError(), signal);
|
|
3156
|
-
else frame = requestAnimationFrame(run);
|
|
3157
|
-
}
|
|
3158
3132
|
signal?.addEventListener(PROMISE_EVENT_NAME, abort, PROMISE_ABORT_OPTIONS);
|
|
3159
|
-
|
|
3133
|
+
const timer = getTimer(TIMER_WAIT, () => {
|
|
3134
|
+
settlePromise(abort, rejector, new PromiseTimeoutError(), signal);
|
|
3135
|
+
}, time);
|
|
3160
3136
|
let rejector;
|
|
3161
|
-
let start;
|
|
3162
3137
|
return Promise.race([promise, new Promise((_, reject) => {
|
|
3163
3138
|
rejector = reject;
|
|
3164
|
-
|
|
3139
|
+
timer();
|
|
3165
3140
|
})]).then((value) => {
|
|
3166
|
-
|
|
3141
|
+
timer.cancel();
|
|
3167
3142
|
signal?.removeEventListener(PROMISE_EVENT_NAME, abort);
|
|
3168
3143
|
return value;
|
|
3169
3144
|
});
|
|
@@ -3178,24 +3153,20 @@ function delay(options) {
|
|
|
3178
3153
|
const { signal, time } = getPromiseOptions(options);
|
|
3179
3154
|
if (signal?.aborted ?? false) return Promise.reject(signal.reason);
|
|
3180
3155
|
function abort() {
|
|
3181
|
-
|
|
3156
|
+
timer.cancel();
|
|
3182
3157
|
rejector(signal.reason);
|
|
3183
3158
|
}
|
|
3184
|
-
|
|
3185
|
-
|
|
3186
|
-
|
|
3187
|
-
else frame = requestAnimationFrame(run);
|
|
3188
|
-
}
|
|
3159
|
+
const timer = getTimer(TIMER_WAIT, () => {
|
|
3160
|
+
settlePromise(abort, resolver, void 0, signal);
|
|
3161
|
+
}, time);
|
|
3189
3162
|
signal?.addEventListener("abort", abort, PROMISE_ABORT_OPTIONS);
|
|
3190
|
-
let frame;
|
|
3191
3163
|
let rejector;
|
|
3192
3164
|
let resolver;
|
|
3193
|
-
let start;
|
|
3194
3165
|
return new Promise((resolve, reject) => {
|
|
3195
3166
|
rejector = reject;
|
|
3196
3167
|
resolver = resolve;
|
|
3197
3168
|
if (time === 0) settlePromise(abort, resolve, void 0, signal);
|
|
3198
|
-
else
|
|
3169
|
+
else timer();
|
|
3199
3170
|
});
|
|
3200
3171
|
}
|
|
3201
3172
|
async function attemptPromise(value, options) {
|
|
@@ -3725,4 +3696,4 @@ var SizedSet = class extends Set {
|
|
|
3725
3696
|
}
|
|
3726
3697
|
}
|
|
3727
3698
|
};
|
|
3728
|
-
export { CancelablePromise,
|
|
3699
|
+
export { CancelablePromise, PromiseTimeoutError, QueueError, SizedMap, SizedSet, attempt, attemptPromise, average, beacon, between, camelCase, cancelable, capitalize, ceil, chunk, clamp, clone, compact, compare, count, debounce, delay, diff, endsWith, equal, error, exists, filter, find, flatten, floor, flow, toResult as fromPromise, toResult, fromQuery, toPromise as fromResult, toPromise, getArray, getColor, getForegroundColor, getHexColor, getHexaColor, getHslColor, getHslaColor, getNormalizedHex, getNumber, getRandomBoolean, getRandomCharacters, getRandomColor, getRandomFloat, getRandomHex, getRandomInteger, getRandomItem, getRandomItems, getRgbColor, getRgbaColor, getString, getUuid, getValue, groupBy, hexToHsl, hexToHsla, hexToRgb, hexToRgba, hslToHex, hslToRgb, hslToRgba, ignoreKey, includes, indexOf, insert, isArrayOrPlainObject, isColor, isConstructor, isEmpty, isError, isFulfilled, isHexColor, isHslColor, isHslLike, isHslaColor, isInstanceOf, isKey, isNonNullable, isNullable, isNullableOrEmpty, isNullableOrWhitespace, isNumber, isNumerical, isObject, isOk, isPlainObject, isPrimitive, isRejected, isResult, isRgbColor, isRgbLike, isRgbaColor, isTypedArray, join, kebabCase, logger, lowerCase, max, median, memoize, merge, min, noop, ok, omit, parse, partition, pascalCase, pick, pipe, promises, push, queue, range, rgbToHex, rgbToHsl, rgbToHsla, round, select, setValue, shuffle, smush, snakeCase, sort, splice, startsWith, sum, template, throttle, timed, times, titleCase, toMap, toQuery, toRecord, toSet, toggle, trim, truncate, tryDecode, tryEncode, unique, unsmush, unwrap, update, upperCase, words };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { noop } from "../internal/function/misc.js";
|
|
2
|
+
import { TIMER_DEBOUNCE, TIMER_THROTTLE, getTimer } from "../internal/function/timer.js";
|
|
3
|
+
import { memoize } from "./memoize.js";
|
|
4
|
+
/**
|
|
5
|
+
* Debounce a function, ensuring it is only called after `time` milliseconds have passed
|
|
6
|
+
*
|
|
7
|
+
* On subsequent calls, the timer is reset and will wait another `time` milliseconds _(and so on...)_
|
|
8
|
+
* @param callback Callback to debounce
|
|
9
|
+
* @param time Time in milliseconds to wait before calling the callback _(defaults to match frame rate)_
|
|
10
|
+
* @returns Debounced callback with a `cancel` method
|
|
11
|
+
*/
|
|
12
|
+
function debounce(callback, time) {
|
|
13
|
+
return getTimer(TIMER_DEBOUNCE, callback, time);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Throttle a function, ensuring it is only called once every `time` milliseconds
|
|
17
|
+
* @param callback Callback to throttle
|
|
18
|
+
* @param time Time in milliseconds to wait before calling the callback again _(defaults to match frame rate)_
|
|
19
|
+
* @returns Throttled callback with a `cancel` method
|
|
20
|
+
*/
|
|
21
|
+
function throttle(callback, time) {
|
|
22
|
+
return getTimer(TIMER_THROTTLE, callback, time);
|
|
23
|
+
}
|
|
24
|
+
export { debounce, memoize, noop, throttle };
|
package/dist/index.js
CHANGED
|
@@ -36,11 +36,9 @@ import { rgbToHex, rgbToHsl, rgbToHsla } from "./color/space/rgb.js";
|
|
|
36
36
|
import { getNormalizedHex, hexToHsl, hexToHsla, hexToRgb, hexToRgba } from "./color/space/hex.js";
|
|
37
37
|
import { hslToHex, hslToRgb, hslToRgba } from "./color/space/hsl.js";
|
|
38
38
|
import { getColor } from "./color/index.js";
|
|
39
|
-
import frame_rate_default from "./internal/frame-rate.js";
|
|
40
|
-
import { debounce } from "./function/debounce.js";
|
|
41
39
|
import { SizedMap } from "./sized/map.js";
|
|
42
40
|
import { memoize } from "./function/memoize.js";
|
|
43
|
-
import { throttle } from "./function/
|
|
41
|
+
import { debounce, throttle } from "./function/index.js";
|
|
44
42
|
import { isError, isOk, isResult } from "./internal/result.js";
|
|
45
43
|
import { flow, pipe } from "./function/work.js";
|
|
46
44
|
import { equal } from "./internal/value/equal.js";
|
|
@@ -72,4 +70,4 @@ import { QueueError, queue } from "./queue.js";
|
|
|
72
70
|
import { getRandomBoolean, getRandomCharacters, getRandomColor, getRandomHex, getRandomItem, getRandomItems } from "./random.js";
|
|
73
71
|
import { attempt } from "./result/index.js";
|
|
74
72
|
import { SizedSet } from "./sized/set.js";
|
|
75
|
-
export { CancelablePromise,
|
|
73
|
+
export { CancelablePromise, PromiseTimeoutError, QueueError, SizedMap, SizedSet, attempt, attemptPromise, average, beacon, between, camelCase, cancelable, capitalize, ceil, chunk, clamp, clone, compact, compare, count, debounce, delay, diff, endsWith, equal, error, exists, filter, find, flatten, floor, flow, toResult as fromPromise, fromQuery, toPromise as fromResult, getArray, getColor, getForegroundColor, getHexColor, getHexaColor, getHslColor, getHslaColor, getNormalizedHex, getNumber, getRandomBoolean, getRandomCharacters, getRandomColor, getRandomFloat, getRandomHex, getRandomInteger, getRandomItem, getRandomItems, getRgbColor, getRgbaColor, getString, getUuid, getValue, groupBy, hexToHsl, hexToHsla, hexToRgb, hexToRgba, hslToHex, hslToRgb, hslToRgba, ignoreKey, includes, indexOf, insert, isArrayOrPlainObject, isColor, isConstructor, isEmpty, isError, isFulfilled, isHexColor, isHslColor, isHslLike, isHslaColor, isInstanceOf, isKey, isNonNullable, isNullable, isNullableOrEmpty, isNullableOrWhitespace, isNumber, isNumerical, isObject, isOk, isPlainObject, isPrimitive, isRejected, isResult, isRgbColor, isRgbLike, isRgbaColor, isTypedArray, join, kebabCase, logger, lowerCase, max, median, memoize, merge, min, noop, ok, omit, parse, partition, pascalCase, pick, pipe, promises, push, queue, range, rgbToHex, rgbToHsl, rgbToHsla, round, select, setValue, shuffle, smush, snakeCase, sort, splice, startsWith, sum, template, throttle, timed, times, titleCase, toMap, toPromise, toQuery, toRecord, toResult, toSet, toggle, trim, truncate, tryDecode, tryEncode, unique, unsmush, unwrap, update, upperCase, words };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
function getInterval(value) {
|
|
2
|
+
return typeof value === "number" && value > 0 ? value : 0;
|
|
3
|
+
}
|
|
4
|
+
function getTimer(type, callback, time) {
|
|
5
|
+
const interval = getInterval(time);
|
|
6
|
+
function run(now) {
|
|
7
|
+
start ??= now;
|
|
8
|
+
if (interval === 0 || now - start >= interval - OFFSET) {
|
|
9
|
+
if (throttle) start = now;
|
|
10
|
+
callback(...args);
|
|
11
|
+
} else frame = requestAnimationFrame(run);
|
|
12
|
+
}
|
|
13
|
+
const throttle = type === TIMER_THROTTLE;
|
|
14
|
+
let args;
|
|
15
|
+
let frame;
|
|
16
|
+
let start;
|
|
17
|
+
const timer = (...parameters) => {
|
|
18
|
+
timer.cancel();
|
|
19
|
+
args = parameters;
|
|
20
|
+
frame = requestAnimationFrame(run);
|
|
21
|
+
};
|
|
22
|
+
timer.cancel = () => {
|
|
23
|
+
cancelAnimationFrame(frame);
|
|
24
|
+
};
|
|
25
|
+
return timer;
|
|
26
|
+
}
|
|
27
|
+
var OFFSET = 5;
|
|
28
|
+
const TIMER_DEBOUNCE = "debounce";
|
|
29
|
+
const TIMER_THROTTLE = "throttle";
|
|
30
|
+
const TIMER_WAIT = "wait";
|
|
31
|
+
export { TIMER_DEBOUNCE, TIMER_THROTTLE, TIMER_WAIT, getTimer };
|
package/dist/promise/delay.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { TIMER_WAIT, getTimer } from "../internal/function/timer.js";
|
|
1
2
|
import { PROMISE_ABORT_OPTIONS } from "./models.js";
|
|
2
3
|
import { getPromiseOptions } from "./helpers.js";
|
|
3
4
|
import { settlePromise } from "./misc.js";
|
|
@@ -5,24 +6,20 @@ function delay(options) {
|
|
|
5
6
|
const { signal, time } = getPromiseOptions(options);
|
|
6
7
|
if (signal?.aborted ?? false) return Promise.reject(signal.reason);
|
|
7
8
|
function abort() {
|
|
8
|
-
|
|
9
|
+
timer.cancel();
|
|
9
10
|
rejector(signal.reason);
|
|
10
11
|
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
else frame = requestAnimationFrame(run);
|
|
15
|
-
}
|
|
12
|
+
const timer = getTimer(TIMER_WAIT, () => {
|
|
13
|
+
settlePromise(abort, resolver, void 0, signal);
|
|
14
|
+
}, time);
|
|
16
15
|
signal?.addEventListener("abort", abort, PROMISE_ABORT_OPTIONS);
|
|
17
|
-
let frame;
|
|
18
16
|
let rejector;
|
|
19
17
|
let resolver;
|
|
20
|
-
let start;
|
|
21
18
|
return new Promise((resolve, reject) => {
|
|
22
19
|
rejector = reject;
|
|
23
20
|
resolver = resolve;
|
|
24
21
|
if (time === 0) settlePromise(abort, resolve, void 0, signal);
|
|
25
|
-
else
|
|
22
|
+
else timer();
|
|
26
23
|
});
|
|
27
24
|
}
|
|
28
25
|
export { delay };
|
package/dist/promise/timed.js
CHANGED
|
@@ -1,25 +1,22 @@
|
|
|
1
|
+
import { TIMER_WAIT, getTimer } from "../internal/function/timer.js";
|
|
1
2
|
import { PROMISE_ABORT_OPTIONS, PROMISE_EVENT_NAME, PROMISE_MESSAGE_EXPECTATION_TIMED, PromiseTimeoutError } from "./models.js";
|
|
2
3
|
import { getPromiseOptions } from "./helpers.js";
|
|
3
4
|
import { settlePromise } from "./misc.js";
|
|
4
5
|
async function getTimedPromise(promise, time, signal) {
|
|
5
6
|
function abort() {
|
|
6
|
-
|
|
7
|
+
timer.cancel();
|
|
7
8
|
rejector(signal.reason);
|
|
8
9
|
}
|
|
9
|
-
function run(now) {
|
|
10
|
-
start ??= now;
|
|
11
|
-
if (time === 0 || now - start >= time - 5) settlePromise(abort, rejector, new PromiseTimeoutError(), signal);
|
|
12
|
-
else frame = requestAnimationFrame(run);
|
|
13
|
-
}
|
|
14
10
|
signal?.addEventListener(PROMISE_EVENT_NAME, abort, PROMISE_ABORT_OPTIONS);
|
|
15
|
-
|
|
11
|
+
const timer = getTimer(TIMER_WAIT, () => {
|
|
12
|
+
settlePromise(abort, rejector, new PromiseTimeoutError(), signal);
|
|
13
|
+
}, time);
|
|
16
14
|
let rejector;
|
|
17
|
-
let start;
|
|
18
15
|
return Promise.race([promise, new Promise((_, reject) => {
|
|
19
16
|
rejector = reject;
|
|
20
|
-
|
|
17
|
+
timer();
|
|
21
18
|
})]).then((value) => {
|
|
22
|
-
|
|
19
|
+
timer.cancel();
|
|
23
20
|
signal?.removeEventListener(PROMISE_EVENT_NAME, abort);
|
|
24
21
|
return value;
|
|
25
22
|
});
|
package/package.json
CHANGED
|
@@ -50,26 +50,10 @@
|
|
|
50
50
|
"types": "./types/color/index.d.ts",
|
|
51
51
|
"default": "./dist/color/index.js"
|
|
52
52
|
},
|
|
53
|
-
"./
|
|
54
|
-
"types": "./types/internal/frame-rate.d.ts",
|
|
55
|
-
"default": "./dist/internal/frame-rate.js"
|
|
56
|
-
},
|
|
57
|
-
"./function/debounce": {
|
|
58
|
-
"types": "./types/function/debounce.d.ts",
|
|
59
|
-
"default": "./dist/function/debounce.js"
|
|
60
|
-
},
|
|
61
|
-
"./function/memoize": {
|
|
53
|
+
"./function": {
|
|
62
54
|
"types": "./types/function/memoize.d.ts",
|
|
63
55
|
"default": "./dist/function/memoize.js"
|
|
64
56
|
},
|
|
65
|
-
"./function/misc": {
|
|
66
|
-
"types": "./types/function/misc.d.ts",
|
|
67
|
-
"default": "./dist/function/misc.js"
|
|
68
|
-
},
|
|
69
|
-
"./function/throttle": {
|
|
70
|
-
"types": "./types/function/throttle.d.ts",
|
|
71
|
-
"default": "./dist/function/throttle.js"
|
|
72
|
-
},
|
|
73
57
|
"./function/work": {
|
|
74
58
|
"types": "./types/function/work.d.ts",
|
|
75
59
|
"default": "./dist/function/work.js"
|
|
@@ -192,5 +176,5 @@
|
|
|
192
176
|
},
|
|
193
177
|
"type": "module",
|
|
194
178
|
"types": "./types/index.d.ts",
|
|
195
|
-
"version": "0.
|
|
179
|
+
"version": "0.152.0"
|
|
196
180
|
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import {getTimer, TIMER_DEBOUNCE, TIMER_THROTTLE} from '../internal/function/timer';
|
|
2
|
+
import type {CancelableCallback, GenericCallback} from '../models';
|
|
3
|
+
|
|
4
|
+
// #region Functions
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Debounce a function, ensuring it is only called after `time` milliseconds have passed
|
|
8
|
+
*
|
|
9
|
+
* On subsequent calls, the timer is reset and will wait another `time` milliseconds _(and so on...)_
|
|
10
|
+
* @param callback Callback to debounce
|
|
11
|
+
* @param time Time in milliseconds to wait before calling the callback _(defaults to match frame rate)_
|
|
12
|
+
* @returns Debounced callback with a `cancel` method
|
|
13
|
+
*/
|
|
14
|
+
export function debounce<Callback extends GenericCallback>(
|
|
15
|
+
callback: Callback,
|
|
16
|
+
time?: number,
|
|
17
|
+
): CancelableCallback<Callback> {
|
|
18
|
+
return getTimer(TIMER_DEBOUNCE, callback, time);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Throttle a function, ensuring it is only called once every `time` milliseconds
|
|
23
|
+
* @param callback Callback to throttle
|
|
24
|
+
* @param time Time in milliseconds to wait before calling the callback again _(defaults to match frame rate)_
|
|
25
|
+
* @returns Throttled callback with a `cancel` method
|
|
26
|
+
*/
|
|
27
|
+
export function throttle<Callback extends GenericCallback>(
|
|
28
|
+
callback: Callback,
|
|
29
|
+
time?: number,
|
|
30
|
+
): CancelableCallback<Callback> {
|
|
31
|
+
return getTimer(TIMER_THROTTLE, callback, time);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// #endregion
|
|
35
|
+
|
|
36
|
+
// #region Exports
|
|
37
|
+
|
|
38
|
+
export {noop} from '../internal/function/misc';
|
|
39
|
+
export {memoize, type Memoized, type MemoizedOptions} from './memoize';
|
|
40
|
+
|
|
41
|
+
// #endregion
|
package/src/index.ts
CHANGED
|
@@ -1,14 +1,10 @@
|
|
|
1
|
-
import FRAME_RATE_MS from './internal/frame-rate';
|
|
2
|
-
|
|
3
1
|
export * from './array/group-by';
|
|
4
2
|
export * from './array/misc';
|
|
5
3
|
export * from './array/to-map';
|
|
6
4
|
export * from './array/to-record';
|
|
7
5
|
export * from './array/unique';
|
|
8
6
|
|
|
9
|
-
export * from './function/
|
|
10
|
-
export * from './function/memoize';
|
|
11
|
-
export * from './function/throttle';
|
|
7
|
+
export * from './function/index';
|
|
12
8
|
export * from './function/work';
|
|
13
9
|
|
|
14
10
|
export * from './internal/function/misc';
|
|
@@ -45,5 +41,3 @@ export * from './random';
|
|
|
45
41
|
export * from './result/index';
|
|
46
42
|
export * from './sized/map';
|
|
47
43
|
export * from './sized/set';
|
|
48
|
-
|
|
49
|
-
export {FRAME_RATE_MS};
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type {CancelableCallback, GenericCallback} from '../../models';
|
|
2
|
+
|
|
3
|
+
// #region Types
|
|
4
|
+
|
|
5
|
+
type TimerType = 'debounce' | 'throttle' | 'wait';
|
|
6
|
+
|
|
7
|
+
// #endregion
|
|
8
|
+
|
|
9
|
+
// #region Functions
|
|
10
|
+
|
|
11
|
+
function getInterval(value: unknown): number {
|
|
12
|
+
return typeof value === 'number' && value > 0 ? value : 0;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function getTimer<Callback extends GenericCallback>(
|
|
16
|
+
type: TimerType,
|
|
17
|
+
callback: Callback,
|
|
18
|
+
time?: number,
|
|
19
|
+
): CancelableCallback<Callback> {
|
|
20
|
+
const interval = getInterval(time);
|
|
21
|
+
|
|
22
|
+
function run(now: DOMHighResTimeStamp): void {
|
|
23
|
+
start ??= now;
|
|
24
|
+
|
|
25
|
+
if (interval === 0 || now - start >= interval - OFFSET) {
|
|
26
|
+
if (throttle) {
|
|
27
|
+
start = now;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
callback(...args);
|
|
31
|
+
} else {
|
|
32
|
+
frame = requestAnimationFrame(run);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const throttle = type === TIMER_THROTTLE;
|
|
37
|
+
|
|
38
|
+
let args: Parameters<Callback>;
|
|
39
|
+
let frame: DOMHighResTimeStamp | undefined;
|
|
40
|
+
let start: DOMHighResTimeStamp;
|
|
41
|
+
|
|
42
|
+
const timer = (...parameters: Parameters<Callback>): void => {
|
|
43
|
+
timer.cancel();
|
|
44
|
+
|
|
45
|
+
args = parameters;
|
|
46
|
+
frame = requestAnimationFrame(run);
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
timer.cancel = (): void => {
|
|
50
|
+
cancelAnimationFrame(frame!);
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
return timer as CancelableCallback<Callback>;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// #endregion
|
|
57
|
+
|
|
58
|
+
// #region Variables
|
|
59
|
+
|
|
60
|
+
const OFFSET = 5;
|
|
61
|
+
|
|
62
|
+
export const TIMER_DEBOUNCE: TimerType = 'debounce';
|
|
63
|
+
|
|
64
|
+
export const TIMER_THROTTLE: TimerType = 'throttle';
|
|
65
|
+
|
|
66
|
+
export const TIMER_WAIT: TimerType = 'wait';
|
|
67
|
+
|
|
68
|
+
// #endregion
|
package/src/promise/delay.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import {getTimer, TIMER_WAIT} from '../internal/function/timer';
|
|
1
2
|
import {getPromiseOptions} from './helpers';
|
|
2
3
|
import {settlePromise} from './misc';
|
|
3
4
|
import {PROMISE_ABORT_OPTIONS, type PromiseOptions} from './models';
|
|
@@ -26,27 +27,23 @@ export function delay(options?: unknown): Promise<void> {
|
|
|
26
27
|
}
|
|
27
28
|
|
|
28
29
|
function abort(): void {
|
|
29
|
-
|
|
30
|
+
timer.cancel();
|
|
30
31
|
|
|
31
32
|
rejector(signal!.reason);
|
|
32
33
|
}
|
|
33
34
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
if (now - start >= time - 5) {
|
|
35
|
+
const timer = getTimer(
|
|
36
|
+
TIMER_WAIT,
|
|
37
|
+
() => {
|
|
38
38
|
settlePromise(abort, resolver, undefined, signal);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
39
|
+
},
|
|
40
|
+
time,
|
|
41
|
+
);
|
|
43
42
|
|
|
44
43
|
signal?.addEventListener('abort', abort, PROMISE_ABORT_OPTIONS);
|
|
45
44
|
|
|
46
|
-
let frame: DOMHighResTimeStamp;
|
|
47
45
|
let rejector: (reason: unknown) => void;
|
|
48
46
|
let resolver: () => void;
|
|
49
|
-
let start: DOMHighResTimeStamp;
|
|
50
47
|
|
|
51
48
|
return new Promise((resolve, reject) => {
|
|
52
49
|
rejector = reject;
|
|
@@ -55,7 +52,7 @@ export function delay(options?: unknown): Promise<void> {
|
|
|
55
52
|
if (time === 0) {
|
|
56
53
|
settlePromise(abort, resolve, undefined, signal);
|
|
57
54
|
} else {
|
|
58
|
-
|
|
55
|
+
timer();
|
|
59
56
|
}
|
|
60
57
|
});
|
|
61
58
|
}
|
package/src/promise/timed.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import {getTimer, TIMER_WAIT} from '../internal/function/timer';
|
|
1
2
|
import type {RequiredKeys} from '../models';
|
|
2
3
|
import {getPromiseOptions} from './helpers';
|
|
3
4
|
import {settlePromise} from './misc';
|
|
@@ -17,36 +18,32 @@ export async function getTimedPromise<Value>(
|
|
|
17
18
|
signal?: AbortSignal,
|
|
18
19
|
): Promise<Value> {
|
|
19
20
|
function abort(): void {
|
|
20
|
-
|
|
21
|
+
timer.cancel();
|
|
21
22
|
|
|
22
23
|
rejector(signal!.reason);
|
|
23
24
|
}
|
|
24
25
|
|
|
25
|
-
|
|
26
|
-
start ??= now;
|
|
26
|
+
signal?.addEventListener(PROMISE_EVENT_NAME, abort, PROMISE_ABORT_OPTIONS);
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
const timer = getTimer(
|
|
29
|
+
TIMER_WAIT,
|
|
30
|
+
() => {
|
|
29
31
|
settlePromise(abort, rejector, new PromiseTimeoutError(), signal);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
signal?.addEventListener(PROMISE_EVENT_NAME, abort, PROMISE_ABORT_OPTIONS);
|
|
32
|
+
},
|
|
33
|
+
time,
|
|
34
|
+
);
|
|
36
35
|
|
|
37
|
-
let frame: DOMHighResTimeStamp;
|
|
38
36
|
let rejector: (reason: unknown) => void;
|
|
39
|
-
let start: DOMHighResTimeStamp;
|
|
40
37
|
|
|
41
38
|
return Promise.race<Value>([
|
|
42
39
|
promise,
|
|
43
40
|
new Promise((_, reject) => {
|
|
44
41
|
rejector = reject;
|
|
45
42
|
|
|
46
|
-
|
|
43
|
+
timer();
|
|
47
44
|
}),
|
|
48
45
|
]).then(value => {
|
|
49
|
-
|
|
46
|
+
timer.cancel();
|
|
50
47
|
|
|
51
48
|
signal?.removeEventListener(PROMISE_EVENT_NAME, abort);
|
|
52
49
|
|
|
@@ -8,3 +8,12 @@ import type { CancelableCallback, GenericCallback } from '../models';
|
|
|
8
8
|
* @returns Debounced callback with a `cancel` method
|
|
9
9
|
*/
|
|
10
10
|
export declare function debounce<Callback extends GenericCallback>(callback: Callback, time?: number): CancelableCallback<Callback>;
|
|
11
|
+
/**
|
|
12
|
+
* Throttle a function, ensuring it is only called once every `time` milliseconds
|
|
13
|
+
* @param callback Callback to throttle
|
|
14
|
+
* @param time Time in milliseconds to wait before calling the callback again _(defaults to match frame rate)_
|
|
15
|
+
* @returns Throttled callback with a `cancel` method
|
|
16
|
+
*/
|
|
17
|
+
export declare function throttle<Callback extends GenericCallback>(callback: Callback, time?: number): CancelableCallback<Callback>;
|
|
18
|
+
export { noop } from '../internal/function/misc';
|
|
19
|
+
export { memoize, type Memoized, type MemoizedOptions } from './memoize';
|
package/types/index.d.ts
CHANGED
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
import FRAME_RATE_MS from './internal/frame-rate';
|
|
2
1
|
export * from './array/group-by';
|
|
3
2
|
export * from './array/misc';
|
|
4
3
|
export * from './array/to-map';
|
|
5
4
|
export * from './array/to-record';
|
|
6
5
|
export * from './array/unique';
|
|
7
|
-
export * from './function/
|
|
8
|
-
export * from './function/memoize';
|
|
9
|
-
export * from './function/throttle';
|
|
6
|
+
export * from './function/index';
|
|
10
7
|
export * from './function/work';
|
|
11
8
|
export * from './internal/function/misc';
|
|
12
9
|
export * from './internal/string';
|
|
@@ -39,4 +36,3 @@ export * from './random';
|
|
|
39
36
|
export * from './result/index';
|
|
40
37
|
export * from './sized/map';
|
|
41
38
|
export * from './sized/set';
|
|
42
|
-
export { FRAME_RATE_MS };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { CancelableCallback, GenericCallback } from '../../models';
|
|
2
|
+
type TimerType = 'debounce' | 'throttle' | 'wait';
|
|
3
|
+
export declare function getTimer<Callback extends GenericCallback>(type: TimerType, callback: Callback, time?: number): CancelableCallback<Callback>;
|
|
4
|
+
export declare const TIMER_DEBOUNCE: TimerType;
|
|
5
|
+
export declare const TIMER_THROTTLE: TimerType;
|
|
6
|
+
export declare const TIMER_WAIT: TimerType;
|
|
7
|
+
export {};
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { getLimiter } from "../internal/function/limiter.js";
|
|
2
|
-
/**
|
|
3
|
-
* Debounce a function, ensuring it is only called after `time` milliseconds have passed
|
|
4
|
-
*
|
|
5
|
-
* On subsequent calls, the timer is reset and will wait another `time` milliseconds _(and so on...)_
|
|
6
|
-
* @param callback Callback to debounce
|
|
7
|
-
* @param time Time in milliseconds to wait before calling the callback _(defaults to match frame rate)_
|
|
8
|
-
* @returns Debounced callback with a `cancel` method
|
|
9
|
-
*/
|
|
10
|
-
function debounce(callback, time) {
|
|
11
|
-
return getLimiter(callback, false, time);
|
|
12
|
-
}
|
|
13
|
-
export { debounce };
|
package/dist/function/misc.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { getLimiter } from "../internal/function/limiter.js";
|
|
2
|
-
/**
|
|
3
|
-
* Throttle a function, ensuring it is only called once every `time` milliseconds
|
|
4
|
-
* @param callback Callback to throttle
|
|
5
|
-
* @param time Time in milliseconds to wait before calling the callback again _(defaults to match frame rate)_
|
|
6
|
-
* @returns Throttled callback with a `cancel` method
|
|
7
|
-
*/
|
|
8
|
-
function throttle(callback, time) {
|
|
9
|
-
return getLimiter(callback, true, time);
|
|
10
|
-
}
|
|
11
|
-
export { throttle };
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
function calculate() {
|
|
2
|
-
return new Promise((resolve) => {
|
|
3
|
-
const values = [];
|
|
4
|
-
let last;
|
|
5
|
-
function step(now) {
|
|
6
|
-
if (last != null) values.push(now - last);
|
|
7
|
-
last = now;
|
|
8
|
-
if (values.length >= TOTAL) resolve(values.sort().slice(TRIM_PART, -TRIM_PART).reduce((first, second) => first + second, 0) / (values.length - TRIM_TOTAL));
|
|
9
|
-
else requestAnimationFrame(step);
|
|
10
|
-
}
|
|
11
|
-
requestAnimationFrame(step);
|
|
12
|
-
});
|
|
13
|
-
}
|
|
14
|
-
var TOTAL = 10;
|
|
15
|
-
var TRIM_PART = 2;
|
|
16
|
-
var TRIM_TOTAL = 4;
|
|
17
|
-
var FRAME_RATE_MS = 1e3 / 60;
|
|
18
|
-
/**
|
|
19
|
-
* A calculated average of the refresh rate of the display _(in milliseconds)_
|
|
20
|
-
*/
|
|
21
|
-
calculate().then((value) => {
|
|
22
|
-
FRAME_RATE_MS = value;
|
|
23
|
-
});
|
|
24
|
-
var frame_rate_default = FRAME_RATE_MS;
|
|
25
|
-
export { frame_rate_default as default };
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import frame_rate_default from "../frame-rate.js";
|
|
2
|
-
function getLimiter(callback, throttler, time) {
|
|
3
|
-
const interval = typeof time === "number" && time >= frame_rate_default ? time : frame_rate_default;
|
|
4
|
-
function step(now, parameters) {
|
|
5
|
-
if (interval === frame_rate_default || now - timestamp >= interval) {
|
|
6
|
-
if (throttler) timestamp = now;
|
|
7
|
-
callback(...parameters);
|
|
8
|
-
} else frame = requestAnimationFrame((next) => {
|
|
9
|
-
step(next, parameters);
|
|
10
|
-
});
|
|
11
|
-
}
|
|
12
|
-
let frame;
|
|
13
|
-
let timestamp;
|
|
14
|
-
const limiter = (...parameters) => {
|
|
15
|
-
limiter.cancel();
|
|
16
|
-
frame = requestAnimationFrame((now) => {
|
|
17
|
-
timestamp ??= now - frame_rate_default;
|
|
18
|
-
step(now, parameters);
|
|
19
|
-
});
|
|
20
|
-
};
|
|
21
|
-
limiter.cancel = () => {
|
|
22
|
-
if (frame != null) {
|
|
23
|
-
cancelAnimationFrame(frame);
|
|
24
|
-
frame = void 0;
|
|
25
|
-
}
|
|
26
|
-
};
|
|
27
|
-
return limiter;
|
|
28
|
-
}
|
|
29
|
-
export { getLimiter };
|
package/src/function/debounce.ts
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import {getLimiter} from '../internal/function/limiter';
|
|
2
|
-
import type {CancelableCallback, GenericCallback} from '../models';
|
|
3
|
-
|
|
4
|
-
// #region Functions
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Debounce a function, ensuring it is only called after `time` milliseconds have passed
|
|
8
|
-
*
|
|
9
|
-
* On subsequent calls, the timer is reset and will wait another `time` milliseconds _(and so on...)_
|
|
10
|
-
* @param callback Callback to debounce
|
|
11
|
-
* @param time Time in milliseconds to wait before calling the callback _(defaults to match frame rate)_
|
|
12
|
-
* @returns Debounced callback with a `cancel` method
|
|
13
|
-
*/
|
|
14
|
-
export function debounce<Callback extends GenericCallback>(
|
|
15
|
-
callback: Callback,
|
|
16
|
-
time?: number,
|
|
17
|
-
): CancelableCallback<Callback> {
|
|
18
|
-
return getLimiter(callback, false, time);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
// #endregion
|
package/src/function/misc.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {noop} from '../internal/function/misc';
|
package/src/function/throttle.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import {getLimiter} from '../internal/function/limiter';
|
|
2
|
-
import type {CancelableCallback, GenericCallback} from '../models';
|
|
3
|
-
|
|
4
|
-
// #region Functions
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Throttle a function, ensuring it is only called once every `time` milliseconds
|
|
8
|
-
* @param callback Callback to throttle
|
|
9
|
-
* @param time Time in milliseconds to wait before calling the callback again _(defaults to match frame rate)_
|
|
10
|
-
* @returns Throttled callback with a `cancel` method
|
|
11
|
-
*/
|
|
12
|
-
export function throttle<Callback extends GenericCallback>(
|
|
13
|
-
callback: Callback,
|
|
14
|
-
time?: number,
|
|
15
|
-
): CancelableCallback<Callback> {
|
|
16
|
-
return getLimiter(callback, true, time);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
// #endregion
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
// #region Functions
|
|
2
|
-
|
|
3
|
-
function calculate(): Promise<number> {
|
|
4
|
-
return new Promise(resolve => {
|
|
5
|
-
const values: number[] = [];
|
|
6
|
-
|
|
7
|
-
let last: DOMHighResTimeStamp;
|
|
8
|
-
|
|
9
|
-
function step(now: DOMHighResTimeStamp): void {
|
|
10
|
-
if (last != null) {
|
|
11
|
-
values.push(now - last);
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
last = now;
|
|
15
|
-
|
|
16
|
-
if (values.length >= TOTAL) {
|
|
17
|
-
const median =
|
|
18
|
-
values
|
|
19
|
-
.sort()
|
|
20
|
-
.slice(TRIM_PART, -TRIM_PART)
|
|
21
|
-
.reduce((first, second) => first + second, 0) /
|
|
22
|
-
(values.length - TRIM_TOTAL);
|
|
23
|
-
|
|
24
|
-
resolve(median);
|
|
25
|
-
} else {
|
|
26
|
-
requestAnimationFrame(step);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
requestAnimationFrame(step);
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// #endregion
|
|
35
|
-
|
|
36
|
-
// #region Variables
|
|
37
|
-
|
|
38
|
-
const TOTAL = 10;
|
|
39
|
-
|
|
40
|
-
const TRIM_PART = 2;
|
|
41
|
-
|
|
42
|
-
const TRIM_TOTAL = 4;
|
|
43
|
-
|
|
44
|
-
let FRAME_RATE_MS = 1000 / 60;
|
|
45
|
-
|
|
46
|
-
// #endregion
|
|
47
|
-
|
|
48
|
-
// #region Initialization
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* A calculated average of the refresh rate of the display _(in milliseconds)_
|
|
52
|
-
*/
|
|
53
|
-
calculate().then(value => {
|
|
54
|
-
FRAME_RATE_MS = value;
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
// #endregion
|
|
58
|
-
|
|
59
|
-
// #region Exports
|
|
60
|
-
|
|
61
|
-
export default FRAME_RATE_MS;
|
|
62
|
-
|
|
63
|
-
// #endregion
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import type {CancelableCallback} from '../../models';
|
|
2
|
-
import type {GenericCallback} from '../../models';
|
|
3
|
-
import FRAME_RATE_MS from '../frame-rate';
|
|
4
|
-
|
|
5
|
-
// #region Functions
|
|
6
|
-
|
|
7
|
-
export function getLimiter<Callback extends GenericCallback>(
|
|
8
|
-
callback: Callback,
|
|
9
|
-
throttler: boolean,
|
|
10
|
-
time?: number,
|
|
11
|
-
): CancelableCallback<Callback> {
|
|
12
|
-
const interval = typeof time === 'number' && time >= FRAME_RATE_MS ? time : FRAME_RATE_MS;
|
|
13
|
-
|
|
14
|
-
function step(now: DOMHighResTimeStamp, parameters: Parameters<Callback>): void {
|
|
15
|
-
if (interval === FRAME_RATE_MS || now - timestamp >= interval) {
|
|
16
|
-
if (throttler) {
|
|
17
|
-
timestamp = now;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
callback(...parameters);
|
|
21
|
-
} else {
|
|
22
|
-
frame = requestAnimationFrame(next => {
|
|
23
|
-
step(next, parameters);
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
let frame: DOMHighResTimeStamp | undefined;
|
|
29
|
-
let timestamp: DOMHighResTimeStamp;
|
|
30
|
-
|
|
31
|
-
const limiter = (...parameters: Parameters<Callback>): void => {
|
|
32
|
-
limiter.cancel();
|
|
33
|
-
|
|
34
|
-
frame = requestAnimationFrame(now => {
|
|
35
|
-
timestamp ??= now - FRAME_RATE_MS;
|
|
36
|
-
|
|
37
|
-
step(now, parameters);
|
|
38
|
-
});
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
limiter.cancel = (): void => {
|
|
42
|
-
if (frame != null) {
|
|
43
|
-
cancelAnimationFrame(frame);
|
|
44
|
-
|
|
45
|
-
frame = undefined;
|
|
46
|
-
}
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
return limiter as CancelableCallback<Callback>;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// #endregion
|
package/types/function/misc.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { noop } from '../internal/function/misc';
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import type { CancelableCallback, GenericCallback } from '../models';
|
|
2
|
-
/**
|
|
3
|
-
* Throttle a function, ensuring it is only called once every `time` milliseconds
|
|
4
|
-
* @param callback Callback to throttle
|
|
5
|
-
* @param time Time in milliseconds to wait before calling the callback again _(defaults to match frame rate)_
|
|
6
|
-
* @returns Throttled callback with a `cancel` method
|
|
7
|
-
*/
|
|
8
|
-
export declare function throttle<Callback extends GenericCallback>(callback: Callback, time?: number): CancelableCallback<Callback>;
|