@oscarpalmer/atoms 0.169.0 → 0.171.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/function/index.d.mts +1 -21
- package/dist/function/index.mjs +1 -24
- package/dist/function/limit.d.mts +49 -0
- package/dist/function/limit.mjs +52 -0
- package/dist/index.d.mts +44 -7
- package/dist/index.mjs +116 -38
- package/dist/internal/function/timer.d.mts +3 -2
- package/dist/internal/function/timer.mjs +57 -7
- package/dist/models.d.mts +11 -2
- package/dist/value/clone.mjs +1 -1
- package/package.json +5 -2
- package/src/function/index.ts +0 -39
- package/src/function/limit.ts +77 -0
- package/src/index.ts +1 -0
- package/src/internal/function/timer.ts +108 -8
- package/src/models.ts +14 -1
- package/src/value/clone.ts +1 -1
|
@@ -1,23 +1,3 @@
|
|
|
1
|
-
import { CancelableCallback, GenericCallback } from "../models.mjs";
|
|
2
1
|
import { noop } from "../internal/function/misc.mjs";
|
|
3
2
|
import { Memoized, MemoizedOptions, memoize } from "./memoize.mjs";
|
|
4
|
-
|
|
5
|
-
//#region src/function/index.d.ts
|
|
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
|
-
declare function debounce<Callback extends GenericCallback>(callback: Callback, time?: number): CancelableCallback<Callback>;
|
|
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
|
-
declare function throttle<Callback extends GenericCallback>(callback: Callback, time?: number): CancelableCallback<Callback>;
|
|
22
|
-
//#endregion
|
|
23
|
-
export { type Memoized, type MemoizedOptions, debounce, memoize, noop, throttle };
|
|
3
|
+
export { type Memoized, type MemoizedOptions, memoize, noop };
|
package/dist/function/index.mjs
CHANGED
|
@@ -1,26 +1,3 @@
|
|
|
1
1
|
import { noop } from "../internal/function/misc.mjs";
|
|
2
|
-
import { TIMER_DEBOUNCE, TIMER_THROTTLE, getTimer } from "../internal/function/timer.mjs";
|
|
3
2
|
import { memoize } from "./memoize.mjs";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Debounce a function, ensuring it is only called after `time` milliseconds have passed
|
|
7
|
-
*
|
|
8
|
-
* On subsequent calls, the timer is reset and will wait another `time` milliseconds _(and so on...)_
|
|
9
|
-
* @param callback Callback to debounce
|
|
10
|
-
* @param time Time in milliseconds to wait before calling the callback _(defaults to match frame rate)_
|
|
11
|
-
* @returns Debounced callback with a `cancel` method
|
|
12
|
-
*/
|
|
13
|
-
function debounce(callback, time) {
|
|
14
|
-
return getTimer(TIMER_DEBOUNCE, callback, time);
|
|
15
|
-
}
|
|
16
|
-
/**
|
|
17
|
-
* Throttle a function, ensuring it is only called once every `time` milliseconds
|
|
18
|
-
* @param callback Callback to throttle
|
|
19
|
-
* @param time Time in milliseconds to wait before calling the callback again _(defaults to match frame rate)_
|
|
20
|
-
* @returns Throttled callback with a `cancel` method
|
|
21
|
-
*/
|
|
22
|
-
function throttle(callback, time) {
|
|
23
|
-
return getTimer(TIMER_THROTTLE, callback, time);
|
|
24
|
-
}
|
|
25
|
-
//#endregion
|
|
26
|
-
export { debounce, memoize, noop, throttle };
|
|
3
|
+
export { memoize, noop };
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { AsyncCancelableCallback, CancelableCallback, GenericAsyncCallback, GenericCallback } from "../models.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/function/limit.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Debounce a function, ensuring it is only called after `time` milliseconds have passed
|
|
6
|
+
*
|
|
7
|
+
* When called, successful _(finished)_ results will resolve and errors will reject.
|
|
8
|
+
*
|
|
9
|
+
* On subsequent calls, existing calls will be canceled _(rejected)_, the timer reset, and will wait another `time` milliseconds before the new call is made _(and so on...)_
|
|
10
|
+
* @param callback Callback to debounce
|
|
11
|
+
* @param time Time in milliseconds to wait before calling the callback _(defaults to `0`; e.g., as soon as possible)_
|
|
12
|
+
* @returns Debounced callback handler with a `cancel` method
|
|
13
|
+
*/
|
|
14
|
+
declare function asyncDebounce<Callback extends GenericAsyncCallback | GenericCallback>(callback: Callback, time?: number): AsyncCancelableCallback<Callback>;
|
|
15
|
+
/**
|
|
16
|
+
* Throttle a function, ensuring it is only called once every `time` milliseconds
|
|
17
|
+
*
|
|
18
|
+
* When called, successful _(finished)_ results will resolve and errors will reject.
|
|
19
|
+
*
|
|
20
|
+
* On subsequent calls, existing calls will be canceled _(rejected)_ and will wait until the next valid time to call the callback again _(and so on...)_
|
|
21
|
+
* @param callback Callback to throttle
|
|
22
|
+
* @param time Time in milliseconds to wait before calling the callback again _(defaults to `0`; e.g., as soon as possible)_
|
|
23
|
+
* @returns Throttled callback handler with a `cancel` method
|
|
24
|
+
*/
|
|
25
|
+
declare function asyncThrottle<Callback extends GenericAsyncCallback | GenericCallback>(callback: Callback, time?: number): AsyncCancelableCallback<Callback>;
|
|
26
|
+
/**
|
|
27
|
+
* Debounce a function, ensuring it is only called after `time` milliseconds have passed
|
|
28
|
+
*
|
|
29
|
+
* On subsequent calls, the timer is reset and will wait another `time` milliseconds _(and so on...)_
|
|
30
|
+
* @param callback Callback to debounce
|
|
31
|
+
* @param time Time in milliseconds to wait before calling the callback _(defaults to `0`; e.g., as soon as possible)_
|
|
32
|
+
* @returns Debounced callback handler with a `cancel` method
|
|
33
|
+
*/
|
|
34
|
+
declare function debounce<Callback extends GenericCallback>(callback: Callback, time?: number): CancelableCallback<Callback>;
|
|
35
|
+
declare namespace debounce {
|
|
36
|
+
var async: typeof asyncDebounce;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Throttle a function, ensuring it is only called once every `time` milliseconds
|
|
40
|
+
* @param callback Callback to throttle
|
|
41
|
+
* @param time Time in milliseconds to wait before calling the callback again _(defaults to `0`; e.g., as soon as possible)_
|
|
42
|
+
* @returns Throttled callback handler with a `cancel` method
|
|
43
|
+
*/
|
|
44
|
+
declare function throttle<Callback extends GenericCallback>(callback: Callback, time?: number): CancelableCallback<Callback>;
|
|
45
|
+
declare namespace throttle {
|
|
46
|
+
var async: typeof asyncThrottle;
|
|
47
|
+
}
|
|
48
|
+
//#endregion
|
|
49
|
+
export { debounce, throttle };
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { TIMER_DEBOUNCE, TIMER_THROTTLE, getAsyncTimer, getTimer } from "../internal/function/timer.mjs";
|
|
2
|
+
//#region src/function/limit.ts
|
|
3
|
+
/**
|
|
4
|
+
* Debounce a function, ensuring it is only called after `time` milliseconds have passed
|
|
5
|
+
*
|
|
6
|
+
* When called, successful _(finished)_ results will resolve and errors will reject.
|
|
7
|
+
*
|
|
8
|
+
* On subsequent calls, existing calls will be canceled _(rejected)_, the timer reset, and will wait another `time` milliseconds before the new call is made _(and so on...)_
|
|
9
|
+
* @param callback Callback to debounce
|
|
10
|
+
* @param time Time in milliseconds to wait before calling the callback _(defaults to `0`; e.g., as soon as possible)_
|
|
11
|
+
* @returns Debounced callback handler with a `cancel` method
|
|
12
|
+
*/
|
|
13
|
+
function asyncDebounce(callback, time) {
|
|
14
|
+
return getAsyncTimer(TIMER_DEBOUNCE, callback, time);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Throttle a function, ensuring it is only called once every `time` milliseconds
|
|
18
|
+
*
|
|
19
|
+
* When called, successful _(finished)_ results will resolve and errors will reject.
|
|
20
|
+
*
|
|
21
|
+
* On subsequent calls, existing calls will be canceled _(rejected)_ and will wait until the next valid time to call the callback again _(and so on...)_
|
|
22
|
+
* @param callback Callback to throttle
|
|
23
|
+
* @param time Time in milliseconds to wait before calling the callback again _(defaults to `0`; e.g., as soon as possible)_
|
|
24
|
+
* @returns Throttled callback handler with a `cancel` method
|
|
25
|
+
*/
|
|
26
|
+
function asyncThrottle(callback, time) {
|
|
27
|
+
return getAsyncTimer(TIMER_THROTTLE, callback, time);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Debounce a function, ensuring it is only called after `time` milliseconds have passed
|
|
31
|
+
*
|
|
32
|
+
* On subsequent calls, the timer is reset and will wait another `time` milliseconds _(and so on...)_
|
|
33
|
+
* @param callback Callback to debounce
|
|
34
|
+
* @param time Time in milliseconds to wait before calling the callback _(defaults to `0`; e.g., as soon as possible)_
|
|
35
|
+
* @returns Debounced callback handler with a `cancel` method
|
|
36
|
+
*/
|
|
37
|
+
function debounce(callback, time) {
|
|
38
|
+
return getTimer(TIMER_DEBOUNCE, callback, time);
|
|
39
|
+
}
|
|
40
|
+
debounce.async = asyncDebounce;
|
|
41
|
+
/**
|
|
42
|
+
* Throttle a function, ensuring it is only called once every `time` milliseconds
|
|
43
|
+
* @param callback Callback to throttle
|
|
44
|
+
* @param time Time in milliseconds to wait before calling the callback again _(defaults to `0`; e.g., as soon as possible)_
|
|
45
|
+
* @returns Throttled callback handler with a `cancel` method
|
|
46
|
+
*/
|
|
47
|
+
function throttle(callback, time) {
|
|
48
|
+
return getTimer(TIMER_THROTTLE, callback, time);
|
|
49
|
+
}
|
|
50
|
+
throttle.async = asyncThrottle;
|
|
51
|
+
//#endregion
|
|
52
|
+
export { debounce, throttle };
|
package/dist/index.d.mts
CHANGED
|
@@ -3,6 +3,15 @@
|
|
|
3
3
|
* A generic array or object
|
|
4
4
|
*/
|
|
5
5
|
type ArrayOrPlainObject = unknown[] | Record<PropertyKey, unknown>;
|
|
6
|
+
/**
|
|
7
|
+
* An asynchronous callback that can be canceled
|
|
8
|
+
*/
|
|
9
|
+
type AsyncCancelableCallback<Callback extends GenericAsyncCallback | GenericCallback> = (ReturnType<Callback> extends Promise<any> ? (...args: Parameters<Callback>) => Promise<Awaited<ReturnType<Callback>>> : (...args: Parameters<Callback>) => Promise<ReturnType<Callback>>) & {
|
|
10
|
+
/**
|
|
11
|
+
* Cancel the callback
|
|
12
|
+
*/
|
|
13
|
+
cancel: () => void;
|
|
14
|
+
};
|
|
6
15
|
/**
|
|
7
16
|
* For mathicng any `void`, `Date`, primitive, or `RegExp` values
|
|
8
17
|
*
|
|
@@ -10,7 +19,7 @@ type ArrayOrPlainObject = unknown[] | Record<PropertyKey, unknown>;
|
|
|
10
19
|
*/
|
|
11
20
|
type BuiltIns = void | Date | Primitive | RegExp;
|
|
12
21
|
/**
|
|
13
|
-
*
|
|
22
|
+
* A synchronous callback that can be canceled
|
|
14
23
|
*/
|
|
15
24
|
type CancelableCallback<Callback extends GenericCallback> = Callback & {
|
|
16
25
|
/**
|
|
@@ -1636,23 +1645,51 @@ type Options = {
|
|
|
1636
1645
|
*/
|
|
1637
1646
|
declare function memoize<Callback extends GenericCallback>(callback: Callback, options?: MemoizedOptions<Callback>): Memoized<Callback>;
|
|
1638
1647
|
//#endregion
|
|
1639
|
-
//#region src/function/
|
|
1648
|
+
//#region src/function/limit.d.ts
|
|
1649
|
+
/**
|
|
1650
|
+
* Debounce a function, ensuring it is only called after `time` milliseconds have passed
|
|
1651
|
+
*
|
|
1652
|
+
* When called, successful _(finished)_ results will resolve and errors will reject.
|
|
1653
|
+
*
|
|
1654
|
+
* On subsequent calls, existing calls will be canceled _(rejected)_, the timer reset, and will wait another `time` milliseconds before the new call is made _(and so on...)_
|
|
1655
|
+
* @param callback Callback to debounce
|
|
1656
|
+
* @param time Time in milliseconds to wait before calling the callback _(defaults to `0`; e.g., as soon as possible)_
|
|
1657
|
+
* @returns Debounced callback handler with a `cancel` method
|
|
1658
|
+
*/
|
|
1659
|
+
declare function asyncDebounce<Callback extends GenericAsyncCallback | GenericCallback>(callback: Callback, time?: number): AsyncCancelableCallback<Callback>;
|
|
1660
|
+
/**
|
|
1661
|
+
* Throttle a function, ensuring it is only called once every `time` milliseconds
|
|
1662
|
+
*
|
|
1663
|
+
* When called, successful _(finished)_ results will resolve and errors will reject.
|
|
1664
|
+
*
|
|
1665
|
+
* On subsequent calls, existing calls will be canceled _(rejected)_ and will wait until the next valid time to call the callback again _(and so on...)_
|
|
1666
|
+
* @param callback Callback to throttle
|
|
1667
|
+
* @param time Time in milliseconds to wait before calling the callback again _(defaults to `0`; e.g., as soon as possible)_
|
|
1668
|
+
* @returns Throttled callback handler with a `cancel` method
|
|
1669
|
+
*/
|
|
1670
|
+
declare function asyncThrottle<Callback extends GenericAsyncCallback | GenericCallback>(callback: Callback, time?: number): AsyncCancelableCallback<Callback>;
|
|
1640
1671
|
/**
|
|
1641
1672
|
* Debounce a function, ensuring it is only called after `time` milliseconds have passed
|
|
1642
1673
|
*
|
|
1643
1674
|
* On subsequent calls, the timer is reset and will wait another `time` milliseconds _(and so on...)_
|
|
1644
1675
|
* @param callback Callback to debounce
|
|
1645
|
-
* @param time Time in milliseconds to wait before calling the callback _(defaults to
|
|
1646
|
-
* @returns Debounced callback with a `cancel` method
|
|
1676
|
+
* @param time Time in milliseconds to wait before calling the callback _(defaults to `0`; e.g., as soon as possible)_
|
|
1677
|
+
* @returns Debounced callback handler with a `cancel` method
|
|
1647
1678
|
*/
|
|
1648
1679
|
declare function debounce<Callback extends GenericCallback>(callback: Callback, time?: number): CancelableCallback<Callback>;
|
|
1680
|
+
declare namespace debounce {
|
|
1681
|
+
var async: typeof asyncDebounce;
|
|
1682
|
+
}
|
|
1649
1683
|
/**
|
|
1650
1684
|
* Throttle a function, ensuring it is only called once every `time` milliseconds
|
|
1651
1685
|
* @param callback Callback to throttle
|
|
1652
|
-
* @param time Time in milliseconds to wait before calling the callback again _(defaults to
|
|
1653
|
-
* @returns Throttled callback with a `cancel` method
|
|
1686
|
+
* @param time Time in milliseconds to wait before calling the callback again _(defaults to `0`; e.g., as soon as possible)_
|
|
1687
|
+
* @returns Throttled callback handler with a `cancel` method
|
|
1654
1688
|
*/
|
|
1655
1689
|
declare function throttle<Callback extends GenericCallback>(callback: Callback, time?: number): CancelableCallback<Callback>;
|
|
1690
|
+
declare namespace throttle {
|
|
1691
|
+
var async: typeof asyncThrottle;
|
|
1692
|
+
}
|
|
1656
1693
|
//#endregion
|
|
1657
1694
|
//#region src/function/once.d.ts
|
|
1658
1695
|
/**
|
|
@@ -4351,4 +4388,4 @@ declare class SizedSet<Value = unknown> extends Set<Value> {
|
|
|
4351
4388
|
get(value: Value, update?: boolean): Value | undefined;
|
|
4352
4389
|
}
|
|
4353
4390
|
//#endregion
|
|
4354
|
-
export { AnyResult, ArrayComparisonSorter, ArrayKeySorter, ArrayOrPlainObject, ArrayPosition, ArrayValueSorter, Asserter, AttemptFlow, AttemptFlowPromise, type Beacon, type BeaconOptions, BuiltIns, CancelableCallback, CancelablePromise, type Color, Constructor, DiffOptions, DiffResult, DiffValue, EqualOptions, Err, EventPosition, ExtendedErr, ExtendedResult, Flow, FlowPromise, FulfilledPromise, GenericAsyncCallback, GenericCallback, type HSLAColor, type HSLColor, HasValue, Key, KeyedValue, type Logger, type Memoized, type MemoizedOptions, MergeOptions, Merger, NestedArray, NestedKeys, NestedPartial, NestedValue, NestedValues, NumericalKeys, NumericalValues, type Observable, type Observer, Ok, OnceAsyncCallback, OnceCallback, PROMISE_ABORT_EVENT, PROMISE_ABORT_OPTIONS, PROMISE_ERROR_NAME, PROMISE_MESSAGE_EXPECTATION_ATTEMPT, PROMISE_MESSAGE_EXPECTATION_RESULT, PROMISE_MESSAGE_EXPECTATION_TIMED, PROMISE_MESSAGE_TIMEOUT, PROMISE_STRATEGY_ALL, PROMISE_STRATEGY_DEFAULT, PROMISE_TYPE_FULFILLED, PROMISE_TYPE_REJECTED, PlainObject, Primitive, PromiseData, PromiseHandlers, PromiseOptions, PromiseParameters, PromiseStrategy, PromiseTimeoutError, PromisesItems, PromisesOptions, PromisesResult, PromisesUnwrapped, PromisesValue, PromisesValues, type Queue, QueueError, type QueueOptions, type Queued, type RGBAColor, type RGBColor, RejectedPromise, RequiredKeys, Result, ResultMatch, RetryError, RetryOptions, SORT_DIRECTION_ASCENDING, SORT_DIRECTION_DESCENDING, Simplify, SizedMap, SizedSet, Smushed, SortDirection, Sorter, type Subscription, TemplateOptions, type Time, ToString, TypedArray, Unsmushed, UnwrapValue, assert, attempt, attemptFlow, attemptPipe, attemptPromise, average, beacon, between, camelCase, cancelable, capitalize, ceil, chunk, clamp, clone, compact, compare, count, debounce, delay, diff, difference, drop, endsWith, endsWithArray, equal, error, exists, filter, find, flatten, floor, flow, fromQuery, toPromise as fromResult, toPromise, getArray, getArrayPosition, getColor, getError, getForegroundColor, getHexColor, getHexaColor, getHslColor, getHslaColor, getNormalizedHex, getNumber, getRandomBoolean, getRandomCharacters, getRandomColor, getRandomFloat, getRandomHex, getRandomInteger, getRandomItem, getRandomItems, getRgbColor, getRgbaColor, getString, getTimedPromise, getUuid, getValue, groupBy, handleResult, hasValue, hexToHsl, hexToHsla, hexToRgb, hexToRgba, hslToHex, hslToRgb, hslToRgba, ignoreKey, includes, includesArray, indexOf, indexOfArray, insert, intersection, 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, matchResult, max, median, memoize, merge, min, move, noop, ok, omit, once, parse, partition, pascalCase, pick, pipe, promises, push, queue, range, retry, rgbToHex, rgbToHsl, rgbToHsla, round, select, setValue, settlePromise, shuffle, slice, smush, snakeCase, sort, splice, startsWith, startsWithArray, sum, swap, take, template, throttle, timed, times, titleCase, toMap, toQuery, toRecord, toResult, toSet, toggle, trim, truncate, tryDecode, tryEncode, union, unique, unsmush, unwrap, update, upperCase, words };
|
|
4391
|
+
export { AnyResult, ArrayComparisonSorter, ArrayKeySorter, ArrayOrPlainObject, ArrayPosition, ArrayValueSorter, Asserter, AsyncCancelableCallback, AttemptFlow, AttemptFlowPromise, type Beacon, type BeaconOptions, BuiltIns, CancelableCallback, CancelablePromise, type Color, Constructor, DiffOptions, DiffResult, DiffValue, EqualOptions, Err, EventPosition, ExtendedErr, ExtendedResult, Flow, FlowPromise, FulfilledPromise, GenericAsyncCallback, GenericCallback, type HSLAColor, type HSLColor, HasValue, Key, KeyedValue, type Logger, type Memoized, type MemoizedOptions, MergeOptions, Merger, NestedArray, NestedKeys, NestedPartial, NestedValue, NestedValues, NumericalKeys, NumericalValues, type Observable, type Observer, Ok, OnceAsyncCallback, OnceCallback, PROMISE_ABORT_EVENT, PROMISE_ABORT_OPTIONS, PROMISE_ERROR_NAME, PROMISE_MESSAGE_EXPECTATION_ATTEMPT, PROMISE_MESSAGE_EXPECTATION_RESULT, PROMISE_MESSAGE_EXPECTATION_TIMED, PROMISE_MESSAGE_TIMEOUT, PROMISE_STRATEGY_ALL, PROMISE_STRATEGY_DEFAULT, PROMISE_TYPE_FULFILLED, PROMISE_TYPE_REJECTED, PlainObject, Primitive, PromiseData, PromiseHandlers, PromiseOptions, PromiseParameters, PromiseStrategy, PromiseTimeoutError, PromisesItems, PromisesOptions, PromisesResult, PromisesUnwrapped, PromisesValue, PromisesValues, type Queue, QueueError, type QueueOptions, type Queued, type RGBAColor, type RGBColor, RejectedPromise, RequiredKeys, Result, ResultMatch, RetryError, RetryOptions, SORT_DIRECTION_ASCENDING, SORT_DIRECTION_DESCENDING, Simplify, SizedMap, SizedSet, Smushed, SortDirection, Sorter, type Subscription, TemplateOptions, type Time, ToString, TypedArray, Unsmushed, UnwrapValue, assert, attempt, attemptFlow, attemptPipe, attemptPromise, average, beacon, between, camelCase, cancelable, capitalize, ceil, chunk, clamp, clone, compact, compare, count, debounce, delay, diff, difference, drop, endsWith, endsWithArray, equal, error, exists, filter, find, flatten, floor, flow, fromQuery, toPromise as fromResult, toPromise, getArray, getArrayPosition, getColor, getError, getForegroundColor, getHexColor, getHexaColor, getHslColor, getHslaColor, getNormalizedHex, getNumber, getRandomBoolean, getRandomCharacters, getRandomColor, getRandomFloat, getRandomHex, getRandomInteger, getRandomItem, getRandomItems, getRgbColor, getRgbaColor, getString, getTimedPromise, getUuid, getValue, groupBy, handleResult, hasValue, hexToHsl, hexToHsla, hexToRgb, hexToRgba, hslToHex, hslToRgb, hslToRgba, ignoreKey, includes, includesArray, indexOf, indexOfArray, insert, intersection, 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, matchResult, max, median, memoize, merge, min, move, noop, ok, omit, once, parse, partition, pascalCase, pick, pipe, promises, push, queue, range, retry, rgbToHex, rgbToHsl, rgbToHsla, round, select, setValue, settlePromise, shuffle, slice, smush, snakeCase, sort, splice, startsWith, startsWithArray, sum, swap, take, template, throttle, timed, times, titleCase, toMap, toQuery, toRecord, toResult, toSet, toggle, trim, truncate, tryDecode, tryEncode, union, unique, unsmush, unwrap, update, upperCase, words };
|
package/dist/index.mjs
CHANGED
|
@@ -1140,38 +1140,6 @@ function assertIs(condition, message, error) {
|
|
|
1140
1140
|
}
|
|
1141
1141
|
const MESSAGE_VALUE_DEFINED = "Expected value to be defined";
|
|
1142
1142
|
//#endregion
|
|
1143
|
-
//#region src/internal/function/timer.ts
|
|
1144
|
-
function getInterval(value) {
|
|
1145
|
-
return typeof value === "number" && value > 0 ? value : 0;
|
|
1146
|
-
}
|
|
1147
|
-
function getTimer(type, callback, time) {
|
|
1148
|
-
const interval = getInterval(time);
|
|
1149
|
-
function run(now) {
|
|
1150
|
-
start ??= now;
|
|
1151
|
-
if (interval === 0 || now - start >= interval - OFFSET) {
|
|
1152
|
-
start = throttle ? now : void 0;
|
|
1153
|
-
callback(...args);
|
|
1154
|
-
} else frame = requestAnimationFrame(run);
|
|
1155
|
-
}
|
|
1156
|
-
const throttle = type === TIMER_THROTTLE;
|
|
1157
|
-
let args;
|
|
1158
|
-
let frame;
|
|
1159
|
-
let start;
|
|
1160
|
-
const timer = (...parameters) => {
|
|
1161
|
-
timer.cancel();
|
|
1162
|
-
args = parameters;
|
|
1163
|
-
frame = requestAnimationFrame(run);
|
|
1164
|
-
};
|
|
1165
|
-
timer.cancel = () => {
|
|
1166
|
-
cancelAnimationFrame(frame);
|
|
1167
|
-
};
|
|
1168
|
-
return timer;
|
|
1169
|
-
}
|
|
1170
|
-
const OFFSET = 5;
|
|
1171
|
-
const TIMER_DEBOUNCE = "debounce";
|
|
1172
|
-
const TIMER_THROTTLE = "throttle";
|
|
1173
|
-
const TIMER_WAIT = "wait";
|
|
1174
|
-
//#endregion
|
|
1175
1143
|
//#region src/internal/function/misc.ts
|
|
1176
1144
|
/**
|
|
1177
1145
|
* A function that does nothing, which can be useful, I guess…
|
|
@@ -1399,27 +1367,137 @@ function memoize(callback, options) {
|
|
|
1399
1367
|
const DEFAULT_CACHE_SIZE = 1024;
|
|
1400
1368
|
const SEPARATOR = "_";
|
|
1401
1369
|
//#endregion
|
|
1402
|
-
//#region src/function/
|
|
1370
|
+
//#region src/internal/function/timer.ts
|
|
1371
|
+
function getAsyncTimer(type, callback, time) {
|
|
1372
|
+
async function run(item) {
|
|
1373
|
+
const now = performance.now();
|
|
1374
|
+
start ??= now;
|
|
1375
|
+
if (interval === 0 || now - start >= interval - OFFSET) {
|
|
1376
|
+
start = throttle ? now : void 0;
|
|
1377
|
+
item.running = true;
|
|
1378
|
+
try {
|
|
1379
|
+
let result = callback(...item.parameters);
|
|
1380
|
+
if (result instanceof Promise) result = await result;
|
|
1381
|
+
item.resolve(result);
|
|
1382
|
+
} catch (error) {
|
|
1383
|
+
item.reject(error);
|
|
1384
|
+
} finally {
|
|
1385
|
+
item.running = false;
|
|
1386
|
+
}
|
|
1387
|
+
} else id = startTimer(() => run(item));
|
|
1388
|
+
}
|
|
1389
|
+
const interval = getInterval(time);
|
|
1390
|
+
const throttle = type === TIMER_THROTTLE;
|
|
1391
|
+
let id;
|
|
1392
|
+
let last;
|
|
1393
|
+
let start;
|
|
1394
|
+
const timer = (...parameters) => {
|
|
1395
|
+
timer.cancel();
|
|
1396
|
+
const next = {
|
|
1397
|
+
parameters,
|
|
1398
|
+
running: false
|
|
1399
|
+
};
|
|
1400
|
+
next.promise = new Promise((resolve, reject) => {
|
|
1401
|
+
next.reject = reject;
|
|
1402
|
+
next.resolve = resolve;
|
|
1403
|
+
});
|
|
1404
|
+
last = next;
|
|
1405
|
+
if (throttle) run(next);
|
|
1406
|
+
else id = startTimer(() => run(next));
|
|
1407
|
+
return next.promise;
|
|
1408
|
+
};
|
|
1409
|
+
timer.cancel = () => {
|
|
1410
|
+
clearTimer(id);
|
|
1411
|
+
if (last != null && !last.running) last.reject();
|
|
1412
|
+
};
|
|
1413
|
+
return timer;
|
|
1414
|
+
}
|
|
1415
|
+
function getInterval(value) {
|
|
1416
|
+
return typeof value === "number" && value > 0 ? value : 0;
|
|
1417
|
+
}
|
|
1418
|
+
function getTimer(type, callback, time) {
|
|
1419
|
+
function run() {
|
|
1420
|
+
const now = performance.now();
|
|
1421
|
+
start ??= now;
|
|
1422
|
+
if (interval === 0 || now - start >= interval - OFFSET) {
|
|
1423
|
+
start = throttle ? now : void 0;
|
|
1424
|
+
callback(...args);
|
|
1425
|
+
} else id = startTimer(run);
|
|
1426
|
+
}
|
|
1427
|
+
const interval = getInterval(time);
|
|
1428
|
+
const throttle = type === TIMER_THROTTLE;
|
|
1429
|
+
let args;
|
|
1430
|
+
let id;
|
|
1431
|
+
let start;
|
|
1432
|
+
const timer = (...parameters) => {
|
|
1433
|
+
timer.cancel();
|
|
1434
|
+
args = parameters;
|
|
1435
|
+
if (throttle) run();
|
|
1436
|
+
else id = startTimer(run);
|
|
1437
|
+
};
|
|
1438
|
+
timer.cancel = () => {
|
|
1439
|
+
clearTimer(id);
|
|
1440
|
+
};
|
|
1441
|
+
return timer;
|
|
1442
|
+
}
|
|
1443
|
+
const OFFSET = 5;
|
|
1444
|
+
const TIMER_DEBOUNCE = "debounce";
|
|
1445
|
+
const TIMER_THROTTLE = "throttle";
|
|
1446
|
+
const TIMER_WAIT = "wait";
|
|
1447
|
+
// istanbul ignore next
|
|
1448
|
+
const clearTimer = typeof cancelAnimationFrame === "function" ? cancelAnimationFrame : clearTimeout;
|
|
1449
|
+
// istanbul ignore next
|
|
1450
|
+
const startTimer = typeof requestAnimationFrame === "function" ? requestAnimationFrame : setTimeout;
|
|
1451
|
+
//#endregion
|
|
1452
|
+
//#region src/function/limit.ts
|
|
1453
|
+
/**
|
|
1454
|
+
* Debounce a function, ensuring it is only called after `time` milliseconds have passed
|
|
1455
|
+
*
|
|
1456
|
+
* When called, successful _(finished)_ results will resolve and errors will reject.
|
|
1457
|
+
*
|
|
1458
|
+
* On subsequent calls, existing calls will be canceled _(rejected)_, the timer reset, and will wait another `time` milliseconds before the new call is made _(and so on...)_
|
|
1459
|
+
* @param callback Callback to debounce
|
|
1460
|
+
* @param time Time in milliseconds to wait before calling the callback _(defaults to `0`; e.g., as soon as possible)_
|
|
1461
|
+
* @returns Debounced callback handler with a `cancel` method
|
|
1462
|
+
*/
|
|
1463
|
+
function asyncDebounce(callback, time) {
|
|
1464
|
+
return getAsyncTimer(TIMER_DEBOUNCE, callback, time);
|
|
1465
|
+
}
|
|
1466
|
+
/**
|
|
1467
|
+
* Throttle a function, ensuring it is only called once every `time` milliseconds
|
|
1468
|
+
*
|
|
1469
|
+
* When called, successful _(finished)_ results will resolve and errors will reject.
|
|
1470
|
+
*
|
|
1471
|
+
* On subsequent calls, existing calls will be canceled _(rejected)_ and will wait until the next valid time to call the callback again _(and so on...)_
|
|
1472
|
+
* @param callback Callback to throttle
|
|
1473
|
+
* @param time Time in milliseconds to wait before calling the callback again _(defaults to `0`; e.g., as soon as possible)_
|
|
1474
|
+
* @returns Throttled callback handler with a `cancel` method
|
|
1475
|
+
*/
|
|
1476
|
+
function asyncThrottle(callback, time) {
|
|
1477
|
+
return getAsyncTimer(TIMER_THROTTLE, callback, time);
|
|
1478
|
+
}
|
|
1403
1479
|
/**
|
|
1404
1480
|
* Debounce a function, ensuring it is only called after `time` milliseconds have passed
|
|
1405
1481
|
*
|
|
1406
1482
|
* On subsequent calls, the timer is reset and will wait another `time` milliseconds _(and so on...)_
|
|
1407
1483
|
* @param callback Callback to debounce
|
|
1408
|
-
* @param time Time in milliseconds to wait before calling the callback _(defaults to
|
|
1409
|
-
* @returns Debounced callback with a `cancel` method
|
|
1484
|
+
* @param time Time in milliseconds to wait before calling the callback _(defaults to `0`; e.g., as soon as possible)_
|
|
1485
|
+
* @returns Debounced callback handler with a `cancel` method
|
|
1410
1486
|
*/
|
|
1411
1487
|
function debounce(callback, time) {
|
|
1412
1488
|
return getTimer(TIMER_DEBOUNCE, callback, time);
|
|
1413
1489
|
}
|
|
1490
|
+
debounce.async = asyncDebounce;
|
|
1414
1491
|
/**
|
|
1415
1492
|
* Throttle a function, ensuring it is only called once every `time` milliseconds
|
|
1416
1493
|
* @param callback Callback to throttle
|
|
1417
|
-
* @param time Time in milliseconds to wait before calling the callback again _(defaults to
|
|
1418
|
-
* @returns Throttled callback with a `cancel` method
|
|
1494
|
+
* @param time Time in milliseconds to wait before calling the callback again _(defaults to `0`; e.g., as soon as possible)_
|
|
1495
|
+
* @returns Throttled callback handler with a `cancel` method
|
|
1419
1496
|
*/
|
|
1420
1497
|
function throttle(callback, time) {
|
|
1421
1498
|
return getTimer(TIMER_THROTTLE, callback, time);
|
|
1422
1499
|
}
|
|
1500
|
+
throttle.async = asyncThrottle;
|
|
1423
1501
|
//#endregion
|
|
1424
1502
|
//#region src/function/once.ts
|
|
1425
1503
|
/**
|
|
@@ -2313,7 +2391,7 @@ function cloneValue(value, depth, references) {
|
|
|
2313
2391
|
case value instanceof Date: return new Date(value.getTime());
|
|
2314
2392
|
case value instanceof RegExp: return cloneRegularExpression(value, depth, references);
|
|
2315
2393
|
case value instanceof Map: return cloneMap(value, depth, references);
|
|
2316
|
-
case value instanceof Node: return cloneNode(value, depth, references);
|
|
2394
|
+
case typeof Node !== "undefined" && value instanceof Node: return cloneNode(value, depth, references);
|
|
2317
2395
|
case value instanceof Set: return cloneSet(value, depth, references);
|
|
2318
2396
|
case isArrayOrPlainObject(value): return clonePlainObject(value, depth, references);
|
|
2319
2397
|
case isTypedArray(value): return cloneTypedArray(value, depth, references);
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { CancelableCallback, GenericCallback } from "../../models.mjs";
|
|
1
|
+
import { AsyncCancelableCallback, CancelableCallback, GenericAsyncCallback, GenericCallback } from "../../models.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/internal/function/timer.d.ts
|
|
4
4
|
type TimerType = 'debounce' | 'throttle' | 'wait';
|
|
5
|
+
declare function getAsyncTimer<Callback extends GenericAsyncCallback | GenericCallback>(type: TimerType, callback: Callback, time?: number): AsyncCancelableCallback<Callback>;
|
|
5
6
|
declare function getTimer<Callback extends GenericCallback>(type: TimerType, callback: Callback, time?: number): CancelableCallback<Callback>;
|
|
6
7
|
declare const TIMER_DEBOUNCE: TimerType;
|
|
7
8
|
declare const TIMER_THROTTLE: TimerType;
|
|
8
9
|
declare const TIMER_WAIT: TimerType;
|
|
9
10
|
//#endregion
|
|
10
|
-
export { TIMER_DEBOUNCE, TIMER_THROTTLE, TIMER_WAIT, getTimer };
|
|
11
|
+
export { TIMER_DEBOUNCE, TIMER_THROTTLE, TIMER_WAIT, getAsyncTimer, getTimer };
|
|
@@ -1,27 +1,73 @@
|
|
|
1
1
|
//#region src/internal/function/timer.ts
|
|
2
|
+
function getAsyncTimer(type, callback, time) {
|
|
3
|
+
async function run(item) {
|
|
4
|
+
const now = performance.now();
|
|
5
|
+
start ??= now;
|
|
6
|
+
if (interval === 0 || now - start >= interval - OFFSET) {
|
|
7
|
+
start = throttle ? now : void 0;
|
|
8
|
+
item.running = true;
|
|
9
|
+
try {
|
|
10
|
+
let result = callback(...item.parameters);
|
|
11
|
+
if (result instanceof Promise) result = await result;
|
|
12
|
+
item.resolve(result);
|
|
13
|
+
} catch (error) {
|
|
14
|
+
item.reject(error);
|
|
15
|
+
} finally {
|
|
16
|
+
item.running = false;
|
|
17
|
+
}
|
|
18
|
+
} else id = startTimer(() => run(item));
|
|
19
|
+
}
|
|
20
|
+
const interval = getInterval(time);
|
|
21
|
+
const throttle = type === TIMER_THROTTLE;
|
|
22
|
+
let id;
|
|
23
|
+
let last;
|
|
24
|
+
let start;
|
|
25
|
+
const timer = (...parameters) => {
|
|
26
|
+
timer.cancel();
|
|
27
|
+
const next = {
|
|
28
|
+
parameters,
|
|
29
|
+
running: false
|
|
30
|
+
};
|
|
31
|
+
next.promise = new Promise((resolve, reject) => {
|
|
32
|
+
next.reject = reject;
|
|
33
|
+
next.resolve = resolve;
|
|
34
|
+
});
|
|
35
|
+
last = next;
|
|
36
|
+
if (throttle) run(next);
|
|
37
|
+
else id = startTimer(() => run(next));
|
|
38
|
+
return next.promise;
|
|
39
|
+
};
|
|
40
|
+
timer.cancel = () => {
|
|
41
|
+
clearTimer(id);
|
|
42
|
+
if (last != null && !last.running) last.reject();
|
|
43
|
+
};
|
|
44
|
+
return timer;
|
|
45
|
+
}
|
|
2
46
|
function getInterval(value) {
|
|
3
47
|
return typeof value === "number" && value > 0 ? value : 0;
|
|
4
48
|
}
|
|
5
49
|
function getTimer(type, callback, time) {
|
|
6
|
-
|
|
7
|
-
|
|
50
|
+
function run() {
|
|
51
|
+
const now = performance.now();
|
|
8
52
|
start ??= now;
|
|
9
53
|
if (interval === 0 || now - start >= interval - OFFSET) {
|
|
10
54
|
start = throttle ? now : void 0;
|
|
11
55
|
callback(...args);
|
|
12
|
-
} else
|
|
56
|
+
} else id = startTimer(run);
|
|
13
57
|
}
|
|
58
|
+
const interval = getInterval(time);
|
|
14
59
|
const throttle = type === TIMER_THROTTLE;
|
|
15
60
|
let args;
|
|
16
|
-
let
|
|
61
|
+
let id;
|
|
17
62
|
let start;
|
|
18
63
|
const timer = (...parameters) => {
|
|
19
64
|
timer.cancel();
|
|
20
65
|
args = parameters;
|
|
21
|
-
|
|
66
|
+
if (throttle) run();
|
|
67
|
+
else id = startTimer(run);
|
|
22
68
|
};
|
|
23
69
|
timer.cancel = () => {
|
|
24
|
-
|
|
70
|
+
clearTimer(id);
|
|
25
71
|
};
|
|
26
72
|
return timer;
|
|
27
73
|
}
|
|
@@ -29,5 +75,9 @@ const OFFSET = 5;
|
|
|
29
75
|
const TIMER_DEBOUNCE = "debounce";
|
|
30
76
|
const TIMER_THROTTLE = "throttle";
|
|
31
77
|
const TIMER_WAIT = "wait";
|
|
78
|
+
// istanbul ignore next
|
|
79
|
+
const clearTimer = typeof cancelAnimationFrame === "function" ? cancelAnimationFrame : clearTimeout;
|
|
80
|
+
// istanbul ignore next
|
|
81
|
+
const startTimer = typeof requestAnimationFrame === "function" ? requestAnimationFrame : setTimeout;
|
|
32
82
|
//#endregion
|
|
33
|
-
export { TIMER_DEBOUNCE, TIMER_THROTTLE, TIMER_WAIT, getTimer };
|
|
83
|
+
export { TIMER_DEBOUNCE, TIMER_THROTTLE, TIMER_WAIT, getAsyncTimer, getTimer };
|
package/dist/models.d.mts
CHANGED
|
@@ -3,6 +3,15 @@
|
|
|
3
3
|
* A generic array or object
|
|
4
4
|
*/
|
|
5
5
|
type ArrayOrPlainObject = unknown[] | Record<PropertyKey, unknown>;
|
|
6
|
+
/**
|
|
7
|
+
* An asynchronous callback that can be canceled
|
|
8
|
+
*/
|
|
9
|
+
type AsyncCancelableCallback<Callback extends GenericAsyncCallback | GenericCallback> = (ReturnType<Callback> extends Promise<any> ? (...args: Parameters<Callback>) => Promise<Awaited<ReturnType<Callback>>> : (...args: Parameters<Callback>) => Promise<ReturnType<Callback>>) & {
|
|
10
|
+
/**
|
|
11
|
+
* Cancel the callback
|
|
12
|
+
*/
|
|
13
|
+
cancel: () => void;
|
|
14
|
+
};
|
|
6
15
|
/**
|
|
7
16
|
* For mathicng any `void`, `Date`, primitive, or `RegExp` values
|
|
8
17
|
*
|
|
@@ -10,7 +19,7 @@ type ArrayOrPlainObject = unknown[] | Record<PropertyKey, unknown>;
|
|
|
10
19
|
*/
|
|
11
20
|
type BuiltIns = void | Date | Primitive | RegExp;
|
|
12
21
|
/**
|
|
13
|
-
*
|
|
22
|
+
* A synchronous callback that can be canceled
|
|
14
23
|
*/
|
|
15
24
|
type CancelableCallback<Callback extends GenericCallback> = Callback & {
|
|
16
25
|
/**
|
|
@@ -135,4 +144,4 @@ type ToString<Value> = Value extends string | number ? `${Value}` : never;
|
|
|
135
144
|
*/
|
|
136
145
|
type TypedArray = Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array | BigInt64Array | BigUint64Array;
|
|
137
146
|
//#endregion
|
|
138
|
-
export { ArrayOrPlainObject, BuiltIns, CancelableCallback, Constructor, EventPosition, GenericAsyncCallback, GenericCallback, Key, KeyedValue, NestedArray, NestedKeys, NestedPartial, NestedValue, NestedValues, NumericalKeys, NumericalValues, OnceAsyncCallback, OnceCallback, PlainObject, Primitive, RequiredKeys, Simplify, ToString, TypedArray };
|
|
147
|
+
export { ArrayOrPlainObject, AsyncCancelableCallback, BuiltIns, CancelableCallback, Constructor, EventPosition, GenericAsyncCallback, GenericCallback, Key, KeyedValue, NestedArray, NestedKeys, NestedPartial, NestedValue, NestedValues, NumericalKeys, NumericalValues, OnceAsyncCallback, OnceCallback, PlainObject, Primitive, RequiredKeys, Simplify, ToString, TypedArray };
|
package/dist/value/clone.mjs
CHANGED
|
@@ -103,7 +103,7 @@ function cloneValue(value, depth, references) {
|
|
|
103
103
|
case value instanceof Date: return new Date(value.getTime());
|
|
104
104
|
case value instanceof RegExp: return cloneRegularExpression(value, depth, references);
|
|
105
105
|
case value instanceof Map: return cloneMap(value, depth, references);
|
|
106
|
-
case value instanceof Node: return cloneNode(value, depth, references);
|
|
106
|
+
case typeof Node !== "undefined" && value instanceof Node: return cloneNode(value, depth, references);
|
|
107
107
|
case value instanceof Set: return cloneSet(value, depth, references);
|
|
108
108
|
case isArrayOrPlainObject(value): return clonePlainObject(value, depth, references);
|
|
109
109
|
case isTypedArray(value): return cloneTypedArray(value, depth, references);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oscarpalmer/atoms",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.171.0",
|
|
4
4
|
"description": "Atomic utilities for making your JavaScript better.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"helper",
|
|
@@ -76,6 +76,10 @@
|
|
|
76
76
|
"types": "./dist/function/assert.d.mts",
|
|
77
77
|
"default": "./dist/function/assert.mjs"
|
|
78
78
|
},
|
|
79
|
+
"./function/limit": {
|
|
80
|
+
"types": "./dist/function/limit.d.mts",
|
|
81
|
+
"default": "./dist/function/limit.mjs"
|
|
82
|
+
},
|
|
79
83
|
"./function/once": {
|
|
80
84
|
"types": "./dist/function/once.d.mts",
|
|
81
85
|
"default": "./dist/function/once.mjs"
|
|
@@ -221,7 +225,6 @@
|
|
|
221
225
|
"tsdown:build": "npx tsdown -c ./tsdown.config.ts",
|
|
222
226
|
"tsdown:watch": "npx tsdown -c ./tsdown.config.ts --watch",
|
|
223
227
|
"test": "npx vp test run --coverage",
|
|
224
|
-
"test:leak": "npx vp test run --detect-async-leaks --coverage",
|
|
225
228
|
"watch": "npx vite build --watch"
|
|
226
229
|
},
|
|
227
230
|
"devDependencies": {
|
package/src/function/index.ts
CHANGED
|
@@ -1,41 +1,2 @@
|
|
|
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
1
|
export {noop} from '../internal/function/misc';
|
|
39
2
|
export {memoize, type Memoized, type MemoizedOptions} from './memoize';
|
|
40
|
-
|
|
41
|
-
// #endregion
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import {getAsyncTimer, getTimer, TIMER_DEBOUNCE, TIMER_THROTTLE} from '../internal/function/timer';
|
|
2
|
+
import type {
|
|
3
|
+
AsyncCancelableCallback,
|
|
4
|
+
CancelableCallback,
|
|
5
|
+
GenericAsyncCallback,
|
|
6
|
+
GenericCallback,
|
|
7
|
+
} from '../models';
|
|
8
|
+
|
|
9
|
+
// #region Functions
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Debounce a function, ensuring it is only called after `time` milliseconds have passed
|
|
13
|
+
*
|
|
14
|
+
* When called, successful _(finished)_ results will resolve and errors will reject.
|
|
15
|
+
*
|
|
16
|
+
* On subsequent calls, existing calls will be canceled _(rejected)_, the timer reset, and will wait another `time` milliseconds before the new call is made _(and so on...)_
|
|
17
|
+
* @param callback Callback to debounce
|
|
18
|
+
* @param time Time in milliseconds to wait before calling the callback _(defaults to `0`; e.g., as soon as possible)_
|
|
19
|
+
* @returns Debounced callback handler with a `cancel` method
|
|
20
|
+
*/
|
|
21
|
+
function asyncDebounce<Callback extends GenericAsyncCallback | GenericCallback>(
|
|
22
|
+
callback: Callback,
|
|
23
|
+
time?: number,
|
|
24
|
+
): AsyncCancelableCallback<Callback> {
|
|
25
|
+
return getAsyncTimer(TIMER_DEBOUNCE, callback, time);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Throttle a function, ensuring it is only called once every `time` milliseconds
|
|
30
|
+
*
|
|
31
|
+
* When called, successful _(finished)_ results will resolve and errors will reject.
|
|
32
|
+
*
|
|
33
|
+
* On subsequent calls, existing calls will be canceled _(rejected)_ and will wait until the next valid time to call the callback again _(and so on...)_
|
|
34
|
+
* @param callback Callback to throttle
|
|
35
|
+
* @param time Time in milliseconds to wait before calling the callback again _(defaults to `0`; e.g., as soon as possible)_
|
|
36
|
+
* @returns Throttled callback handler with a `cancel` method
|
|
37
|
+
*/
|
|
38
|
+
function asyncThrottle<Callback extends GenericAsyncCallback | GenericCallback>(
|
|
39
|
+
callback: Callback,
|
|
40
|
+
time?: number,
|
|
41
|
+
): AsyncCancelableCallback<Callback> {
|
|
42
|
+
return getAsyncTimer(TIMER_THROTTLE, callback, time);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Debounce a function, ensuring it is only called after `time` milliseconds have passed
|
|
47
|
+
*
|
|
48
|
+
* On subsequent calls, the timer is reset and will wait another `time` milliseconds _(and so on...)_
|
|
49
|
+
* @param callback Callback to debounce
|
|
50
|
+
* @param time Time in milliseconds to wait before calling the callback _(defaults to `0`; e.g., as soon as possible)_
|
|
51
|
+
* @returns Debounced callback handler with a `cancel` method
|
|
52
|
+
*/
|
|
53
|
+
export function debounce<Callback extends GenericCallback>(
|
|
54
|
+
callback: Callback,
|
|
55
|
+
time?: number,
|
|
56
|
+
): CancelableCallback<Callback> {
|
|
57
|
+
return getTimer(TIMER_DEBOUNCE, callback, time);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
debounce.async = asyncDebounce;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Throttle a function, ensuring it is only called once every `time` milliseconds
|
|
64
|
+
* @param callback Callback to throttle
|
|
65
|
+
* @param time Time in milliseconds to wait before calling the callback again _(defaults to `0`; e.g., as soon as possible)_
|
|
66
|
+
* @returns Throttled callback handler with a `cancel` method
|
|
67
|
+
*/
|
|
68
|
+
export function throttle<Callback extends GenericCallback>(
|
|
69
|
+
callback: Callback,
|
|
70
|
+
time?: number,
|
|
71
|
+
): CancelableCallback<Callback> {
|
|
72
|
+
return getTimer(TIMER_THROTTLE, callback, time);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
throttle.async = asyncThrottle;
|
|
76
|
+
|
|
77
|
+
// #endregion
|
package/src/index.ts
CHANGED
|
@@ -1,13 +1,101 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
AsyncCancelableCallback,
|
|
3
|
+
CancelableCallback,
|
|
4
|
+
GenericAsyncCallback,
|
|
5
|
+
GenericCallback,
|
|
6
|
+
} from '../../models';
|
|
2
7
|
|
|
3
8
|
// #region Types
|
|
4
9
|
|
|
10
|
+
type AsyncItem = {
|
|
11
|
+
parameters: unknown[];
|
|
12
|
+
promise: Promise<unknown>;
|
|
13
|
+
reject: (reason?: unknown) => void;
|
|
14
|
+
resolve: (value?: unknown) => void;
|
|
15
|
+
running: boolean;
|
|
16
|
+
};
|
|
17
|
+
|
|
5
18
|
type TimerType = 'debounce' | 'throttle' | 'wait';
|
|
6
19
|
|
|
7
20
|
// #endregion
|
|
8
21
|
|
|
9
22
|
// #region Functions
|
|
10
23
|
|
|
24
|
+
export function getAsyncTimer<Callback extends GenericAsyncCallback | GenericCallback>(
|
|
25
|
+
type: TimerType,
|
|
26
|
+
callback: Callback,
|
|
27
|
+
time?: number,
|
|
28
|
+
): AsyncCancelableCallback<Callback> {
|
|
29
|
+
async function run(item: AsyncItem): Promise<void> {
|
|
30
|
+
const now = performance.now();
|
|
31
|
+
|
|
32
|
+
start ??= now;
|
|
33
|
+
|
|
34
|
+
if (interval === 0 || now - start >= interval - OFFSET) {
|
|
35
|
+
start = throttle ? now : undefined;
|
|
36
|
+
|
|
37
|
+
item.running = true;
|
|
38
|
+
|
|
39
|
+
try {
|
|
40
|
+
let result = callback(...item.parameters);
|
|
41
|
+
|
|
42
|
+
if (result instanceof Promise) {
|
|
43
|
+
result = await result;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
item.resolve(result);
|
|
47
|
+
} catch (error) {
|
|
48
|
+
item.reject(error);
|
|
49
|
+
} finally {
|
|
50
|
+
item.running = false;
|
|
51
|
+
}
|
|
52
|
+
} else {
|
|
53
|
+
id = startTimer(() => run(item));
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const interval = getInterval(time);
|
|
58
|
+
const throttle = type === TIMER_THROTTLE;
|
|
59
|
+
|
|
60
|
+
let id: number;
|
|
61
|
+
let last: AsyncItem;
|
|
62
|
+
let start: number | undefined;
|
|
63
|
+
|
|
64
|
+
const timer = (...parameters: Parameters<Callback>): Promise<unknown> => {
|
|
65
|
+
timer.cancel();
|
|
66
|
+
|
|
67
|
+
const next: AsyncItem = {
|
|
68
|
+
parameters,
|
|
69
|
+
running: false,
|
|
70
|
+
} as never;
|
|
71
|
+
|
|
72
|
+
next.promise = new Promise<unknown>((resolve, reject) => {
|
|
73
|
+
next.reject = reject;
|
|
74
|
+
next.resolve = resolve;
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
last = next;
|
|
78
|
+
|
|
79
|
+
if (throttle) {
|
|
80
|
+
run(next);
|
|
81
|
+
} else {
|
|
82
|
+
id = startTimer(() => run(next));
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return next.promise;
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
timer.cancel = (): void => {
|
|
89
|
+
clearTimer(id);
|
|
90
|
+
|
|
91
|
+
if (last != null && !last.running) {
|
|
92
|
+
last.reject();
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
return timer as AsyncCancelableCallback<Callback>;
|
|
97
|
+
}
|
|
98
|
+
|
|
11
99
|
function getInterval(value: unknown): number {
|
|
12
100
|
return typeof value === 'number' && value > 0 ? value : 0;
|
|
13
101
|
}
|
|
@@ -17,9 +105,9 @@ export function getTimer<Callback extends GenericCallback>(
|
|
|
17
105
|
callback: Callback,
|
|
18
106
|
time?: number,
|
|
19
107
|
): CancelableCallback<Callback> {
|
|
20
|
-
|
|
108
|
+
function run(): void {
|
|
109
|
+
const now = performance.now();
|
|
21
110
|
|
|
22
|
-
function run(now: DOMHighResTimeStamp): void {
|
|
23
111
|
start ??= now;
|
|
24
112
|
|
|
25
113
|
if (interval === 0 || now - start >= interval - OFFSET) {
|
|
@@ -27,25 +115,31 @@ export function getTimer<Callback extends GenericCallback>(
|
|
|
27
115
|
|
|
28
116
|
callback(...args);
|
|
29
117
|
} else {
|
|
30
|
-
|
|
118
|
+
id = startTimer(run);
|
|
31
119
|
}
|
|
32
120
|
}
|
|
33
121
|
|
|
122
|
+
const interval = getInterval(time);
|
|
34
123
|
const throttle = type === TIMER_THROTTLE;
|
|
35
124
|
|
|
36
125
|
let args: Parameters<Callback>;
|
|
37
|
-
let
|
|
38
|
-
let start:
|
|
126
|
+
let id: number;
|
|
127
|
+
let start: number | undefined;
|
|
39
128
|
|
|
40
129
|
const timer = (...parameters: Parameters<Callback>): void => {
|
|
41
130
|
timer.cancel();
|
|
42
131
|
|
|
43
132
|
args = parameters;
|
|
44
|
-
|
|
133
|
+
|
|
134
|
+
if (throttle) {
|
|
135
|
+
run();
|
|
136
|
+
} else {
|
|
137
|
+
id = startTimer(run);
|
|
138
|
+
}
|
|
45
139
|
};
|
|
46
140
|
|
|
47
141
|
timer.cancel = (): void => {
|
|
48
|
-
|
|
142
|
+
clearTimer(id);
|
|
49
143
|
};
|
|
50
144
|
|
|
51
145
|
return timer as CancelableCallback<Callback>;
|
|
@@ -63,4 +157,10 @@ export const TIMER_THROTTLE: TimerType = 'throttle';
|
|
|
63
157
|
|
|
64
158
|
export const TIMER_WAIT: TimerType = 'wait';
|
|
65
159
|
|
|
160
|
+
// istanbul ignore next
|
|
161
|
+
const clearTimer = typeof cancelAnimationFrame === 'function' ? cancelAnimationFrame : clearTimeout;
|
|
162
|
+
|
|
163
|
+
// istanbul ignore next
|
|
164
|
+
const startTimer = typeof requestAnimationFrame === 'function' ? requestAnimationFrame : setTimeout;
|
|
165
|
+
|
|
66
166
|
// #endregion
|
package/src/models.ts
CHANGED
|
@@ -5,6 +5,19 @@
|
|
|
5
5
|
*/
|
|
6
6
|
export type ArrayOrPlainObject = unknown[] | Record<PropertyKey, unknown>;
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* An asynchronous callback that can be canceled
|
|
10
|
+
*/
|
|
11
|
+
export type AsyncCancelableCallback<Callback extends GenericAsyncCallback | GenericCallback> =
|
|
12
|
+
(ReturnType<Callback> extends Promise<any>
|
|
13
|
+
? (...args: Parameters<Callback>) => Promise<Awaited<ReturnType<Callback>>>
|
|
14
|
+
: (...args: Parameters<Callback>) => Promise<ReturnType<Callback>>) & {
|
|
15
|
+
/**
|
|
16
|
+
* Cancel the callback
|
|
17
|
+
*/
|
|
18
|
+
cancel: () => void;
|
|
19
|
+
};
|
|
20
|
+
|
|
8
21
|
/**
|
|
9
22
|
* For mathicng any `void`, `Date`, primitive, or `RegExp` values
|
|
10
23
|
*
|
|
@@ -13,7 +26,7 @@ export type ArrayOrPlainObject = unknown[] | Record<PropertyKey, unknown>;
|
|
|
13
26
|
export type BuiltIns = void | Date | Primitive | RegExp;
|
|
14
27
|
|
|
15
28
|
/**
|
|
16
|
-
*
|
|
29
|
+
* A synchronous callback that can be canceled
|
|
17
30
|
*/
|
|
18
31
|
export type CancelableCallback<Callback extends GenericCallback> = Callback & {
|
|
19
32
|
/**
|
package/src/value/clone.ts
CHANGED
|
@@ -243,7 +243,7 @@ function cloneValue(value: unknown, depth: number, references: WeakMap<WeakKey,
|
|
|
243
243
|
case value instanceof Map:
|
|
244
244
|
return cloneMap(value, depth, references);
|
|
245
245
|
|
|
246
|
-
case value instanceof Node:
|
|
246
|
+
case typeof Node !== 'undefined' && value instanceof Node:
|
|
247
247
|
return cloneNode(value, depth, references);
|
|
248
248
|
|
|
249
249
|
case value instanceof Set:
|