@stacksjs/browser 0.65.0 → 0.67.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/index.js +4 -127
- package/dist/utils/sleep.d.ts +0 -6
- package/package.json +4 -6
- package/dist/index.js.map +0 -90
- package/src/index.ts +0 -1
- package/src/utils/base.ts +0 -12
- package/src/utils/debounce.ts +0 -1
- package/src/utils/function.ts +0 -32
- package/src/utils/guards.ts +0 -39
- package/src/utils/index.ts +0 -11
- package/src/utils/math.ts +0 -30
- package/src/utils/promise.ts +0 -134
- package/src/utils/regex.ts +0 -42
- package/src/utils/retry.ts +0 -43
- package/src/utils/sleep.ts +0 -125
- package/src/utils/throttle.ts +0 -47
- package/src/utils/vendors.ts +0 -258
package/src/index.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './utils/'
|
package/src/utils/base.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
export { toString } from '@stacksjs/strings'
|
|
2
|
-
|
|
3
|
-
// export function assert(condition: boolean, message: string): asserts condition {
|
|
4
|
-
// if (!condition)
|
|
5
|
-
// throw new Error(message)
|
|
6
|
-
// }
|
|
7
|
-
|
|
8
|
-
// export function noop() {}
|
|
9
|
-
|
|
10
|
-
export async function loop(times: number, callback: any): Promise<void> {
|
|
11
|
-
Array.from({ length: times }).forEach(async (_, i) => await callback(i))
|
|
12
|
-
}
|
package/src/utils/debounce.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { debounce } from 'perfect-debounce'
|
package/src/utils/function.ts
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import type { Fn, Nullable } from '@stacksjs/types'
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Call every function in an array
|
|
5
|
-
*/
|
|
6
|
-
export function batchInvoke(functions: Nullable<Fn>[]): void {
|
|
7
|
-
functions.forEach(fn => fn?.())
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
// /**
|
|
11
|
-
// * Call the function
|
|
12
|
-
// */
|
|
13
|
-
// export function invoke(fn: Fn) {
|
|
14
|
-
// return fn()
|
|
15
|
-
// }
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Pass the value through the callback, and return the value
|
|
19
|
-
*
|
|
20
|
-
* @example
|
|
21
|
-
* ```
|
|
22
|
-
* function createUser(name: string): User {
|
|
23
|
-
* return tap(new User, user => {
|
|
24
|
-
* user.name = name
|
|
25
|
-
* })
|
|
26
|
-
* }
|
|
27
|
-
* ```
|
|
28
|
-
*/
|
|
29
|
-
export function tap<T>(value: T, callback: (value: T) => void): T {
|
|
30
|
-
callback(value)
|
|
31
|
-
return value
|
|
32
|
-
}
|
package/src/utils/guards.ts
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Type guard to filter out null-ish values
|
|
3
|
-
*
|
|
4
|
-
* @category Guards
|
|
5
|
-
* @example array.filter(notNullish)
|
|
6
|
-
*/
|
|
7
|
-
export function notNullish<T>(v: T | null | undefined): v is NonNullable<T> {
|
|
8
|
-
return v != null
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Type guard to filter out null values
|
|
13
|
-
*
|
|
14
|
-
* @category Guards
|
|
15
|
-
* @example array.filter(noNull)
|
|
16
|
-
*/
|
|
17
|
-
export function noNull<T>(v: T | null): v is Exclude<T, null> {
|
|
18
|
-
return v !== null
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Type guard to filter out null-ish values
|
|
23
|
-
*
|
|
24
|
-
* @category Guards
|
|
25
|
-
* @example array.filter(notUndefined)
|
|
26
|
-
*/
|
|
27
|
-
export function notUndefined<T>(v: T): v is Exclude<T, undefined> {
|
|
28
|
-
return v !== undefined
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Type guard to filter out falsy values
|
|
33
|
-
*
|
|
34
|
-
* @category Guards
|
|
35
|
-
* @example array.filter(isTruthy)
|
|
36
|
-
*/
|
|
37
|
-
export function isTruthy<T>(v: T): v is NonNullable<T> {
|
|
38
|
-
return Boolean(v)
|
|
39
|
-
}
|
package/src/utils/index.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
export * from './base'
|
|
2
|
-
export * from './debounce'
|
|
3
|
-
export * from './function'
|
|
4
|
-
export * from './guards'
|
|
5
|
-
export * from './math'
|
|
6
|
-
export * from './promise'
|
|
7
|
-
export * from './regex'
|
|
8
|
-
export * from './retry'
|
|
9
|
-
export * from './sleep'
|
|
10
|
-
export * from './throttle'
|
|
11
|
-
export * from './vendors'
|
package/src/utils/math.ts
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
export const clamp = (n: number, min: number, max: number): number => Math.min(max, Math.max(min, n))
|
|
2
|
-
|
|
3
|
-
export function rand(min: number, max: number): number {
|
|
4
|
-
min = Math.ceil(min)
|
|
5
|
-
max = Math.floor(max)
|
|
6
|
-
return Math.floor(Math.random() * (max - min + 1)) + min
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
// not, -> exported as well in ../regex
|
|
10
|
-
export {
|
|
11
|
-
and,
|
|
12
|
-
createGenericProjection,
|
|
13
|
-
createProjection,
|
|
14
|
-
logicNot,
|
|
15
|
-
logicOr,
|
|
16
|
-
or,
|
|
17
|
-
useAbs,
|
|
18
|
-
useAverage,
|
|
19
|
-
useCeil,
|
|
20
|
-
useClamp,
|
|
21
|
-
useFloor,
|
|
22
|
-
useMath,
|
|
23
|
-
useMax,
|
|
24
|
-
useMin,
|
|
25
|
-
usePrecision,
|
|
26
|
-
useProjection,
|
|
27
|
-
useRound,
|
|
28
|
-
useSum,
|
|
29
|
-
useTrunc,
|
|
30
|
-
} from '@vueuse/math'
|
package/src/utils/promise.ts
DELETED
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
export interface SingletonPromiseReturn<T> {
|
|
2
|
-
(): Promise<T>
|
|
3
|
-
/**
|
|
4
|
-
* Reset current staled promise.
|
|
5
|
-
* Await it to have proper shutdown.
|
|
6
|
-
*/
|
|
7
|
-
reset: () => Promise<void>
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
// export { peek } from 'bun'
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Promise with `resolve` and `reject` methods of itself
|
|
14
|
-
*/
|
|
15
|
-
export interface ControlledPromise<T = void> extends Promise<T> {
|
|
16
|
-
resolve: (value: T | PromiseLike<T>) => void
|
|
17
|
-
reject: (reason?: any) => void
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Create singleton promise function.
|
|
22
|
-
*
|
|
23
|
-
* @category Promise
|
|
24
|
-
*/
|
|
25
|
-
export function createSingletonPromise<T>(fn: () => Promise<T>): SingletonPromiseReturn<T> {
|
|
26
|
-
let _promise: Promise<T> | undefined
|
|
27
|
-
|
|
28
|
-
function wrapper() {
|
|
29
|
-
if (!_promise)
|
|
30
|
-
_promise = fn()
|
|
31
|
-
return _promise
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
wrapper.reset = async () => {
|
|
35
|
-
const _prev = _promise
|
|
36
|
-
_promise = undefined
|
|
37
|
-
if (_prev)
|
|
38
|
-
await _prev
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
return wrapper
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Create a promise lock.
|
|
46
|
-
*
|
|
47
|
-
* @category Promise
|
|
48
|
-
* @example
|
|
49
|
-
* ```
|
|
50
|
-
* const lock = createPromiseLock()
|
|
51
|
-
*
|
|
52
|
-
* lock.run(async () => {
|
|
53
|
-
* await doSomething()
|
|
54
|
-
* })
|
|
55
|
-
*
|
|
56
|
-
* // in anther context:
|
|
57
|
-
* await lock.wait() // it will wait all tasking finished
|
|
58
|
-
* ```
|
|
59
|
-
*/
|
|
60
|
-
export function createPromiseLock() {
|
|
61
|
-
let currentPromise = Promise.resolve()
|
|
62
|
-
const queue: Promise<any>[] = []
|
|
63
|
-
|
|
64
|
-
return {
|
|
65
|
-
async run<T = void>(fn: () => Promise<T>): Promise<T> {
|
|
66
|
-
const runTask = async (): Promise<T> => {
|
|
67
|
-
await currentPromise
|
|
68
|
-
return fn()
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
const taskPromise = runTask()
|
|
72
|
-
queue.push(taskPromise)
|
|
73
|
-
|
|
74
|
-
currentPromise = taskPromise
|
|
75
|
-
.catch(() => {})
|
|
76
|
-
.finally(() => {
|
|
77
|
-
const index = queue.indexOf(taskPromise)
|
|
78
|
-
if (index > -1)
|
|
79
|
-
queue.splice(index, 1)
|
|
80
|
-
}) as Promise<void>
|
|
81
|
-
|
|
82
|
-
return taskPromise
|
|
83
|
-
},
|
|
84
|
-
|
|
85
|
-
async wait(): Promise<void> {
|
|
86
|
-
while (queue.length > 0) {
|
|
87
|
-
await Promise.all(queue)
|
|
88
|
-
}
|
|
89
|
-
},
|
|
90
|
-
|
|
91
|
-
isWaiting(): boolean {
|
|
92
|
-
return queue.length > 0
|
|
93
|
-
},
|
|
94
|
-
|
|
95
|
-
clear(): void {
|
|
96
|
-
queue.length = 0
|
|
97
|
-
currentPromise = Promise.resolve()
|
|
98
|
-
},
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* Return a Promise with `resolve` and `reject` methods
|
|
104
|
-
*
|
|
105
|
-
* @category Promise
|
|
106
|
-
* @example
|
|
107
|
-
* ```
|
|
108
|
-
* const promise = createControlledPromise()
|
|
109
|
-
*
|
|
110
|
-
* await promise
|
|
111
|
-
*
|
|
112
|
-
* // in anther context:
|
|
113
|
-
* promise.resolve(data)
|
|
114
|
-
* ```
|
|
115
|
-
*/
|
|
116
|
-
export function createControlledPromise<T>(): ControlledPromise<T> {
|
|
117
|
-
let resolve: any
|
|
118
|
-
let reject: any
|
|
119
|
-
|
|
120
|
-
const promise = new Promise<T>((_resolve, _reject) => {
|
|
121
|
-
resolve = _resolve
|
|
122
|
-
reject = _reject
|
|
123
|
-
}) as ControlledPromise<T>
|
|
124
|
-
|
|
125
|
-
promise.resolve = resolve
|
|
126
|
-
|
|
127
|
-
promise.reject = reject
|
|
128
|
-
return promise
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* Create a promise that will be resolved after `ms` milliseconds.
|
|
133
|
-
*/
|
|
134
|
-
// export { sleep, sleepSync } from 'bun'
|
package/src/utils/regex.ts
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
export type {
|
|
2
|
-
Flag,
|
|
3
|
-
Input,
|
|
4
|
-
MagicRegExp,
|
|
5
|
-
MagicRegExpMatchArray,
|
|
6
|
-
MapToStringCapturedBy,
|
|
7
|
-
StringCapturedBy,
|
|
8
|
-
} from 'magic-regexp'
|
|
9
|
-
export {
|
|
10
|
-
anyOf,
|
|
11
|
-
carriageReturn,
|
|
12
|
-
caseInsensitive,
|
|
13
|
-
char,
|
|
14
|
-
charIn,
|
|
15
|
-
charNotIn,
|
|
16
|
-
digit,
|
|
17
|
-
dotAll,
|
|
18
|
-
exactly,
|
|
19
|
-
global,
|
|
20
|
-
letter,
|
|
21
|
-
linefeed,
|
|
22
|
-
maybe,
|
|
23
|
-
multiline,
|
|
24
|
-
not,
|
|
25
|
-
oneOrMore,
|
|
26
|
-
sticky,
|
|
27
|
-
tab,
|
|
28
|
-
unicode,
|
|
29
|
-
whitespace,
|
|
30
|
-
withIndices,
|
|
31
|
-
word,
|
|
32
|
-
wordBoundary,
|
|
33
|
-
wordChar,
|
|
34
|
-
} from 'magic-regexp'
|
|
35
|
-
|
|
36
|
-
// export function caseInsensitive(pattern: string): RegExp {
|
|
37
|
-
// return new RegExp(pattern, 'i')
|
|
38
|
-
// }
|
|
39
|
-
|
|
40
|
-
export function createRegExp(pattern: string, options: { flags?: string } = {}): RegExp {
|
|
41
|
-
return new RegExp(pattern, options.flags)
|
|
42
|
-
}
|
package/src/utils/retry.ts
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
// eslint-disable-next-line ts/no-unsafe-function-type
|
|
2
|
-
export function retry(fn: Function, options: any): Promise<any> {
|
|
3
|
-
const { retries = 3, initialDelay = 1000, backoffFactor = 2, jitter = true } = options
|
|
4
|
-
|
|
5
|
-
return new Promise((resolve, reject) => {
|
|
6
|
-
let attemptCount = 0
|
|
7
|
-
|
|
8
|
-
const attempt = async () => {
|
|
9
|
-
try {
|
|
10
|
-
resolve(await fn())
|
|
11
|
-
}
|
|
12
|
-
catch (err) {
|
|
13
|
-
if (attemptCount >= retries) {
|
|
14
|
-
reject(err)
|
|
15
|
-
}
|
|
16
|
-
else {
|
|
17
|
-
const delay = calculateDelay(attemptCount, initialDelay, backoffFactor, jitter)
|
|
18
|
-
setTimeout(() => attempt(), delay)
|
|
19
|
-
attemptCount++
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
attempt()
|
|
25
|
-
})
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export function calculateDelay(
|
|
29
|
-
attemptCount: number,
|
|
30
|
-
initialDelay: number,
|
|
31
|
-
backoffFactor: number,
|
|
32
|
-
jitter?: boolean,
|
|
33
|
-
): number {
|
|
34
|
-
let delay = initialDelay * backoffFactor ** attemptCount
|
|
35
|
-
|
|
36
|
-
if (jitter) {
|
|
37
|
-
const random = Math.random() // Generates a number between 0 and 1
|
|
38
|
-
const jitterValue = delay * 0.3 // Jitter will be up to 30% of the delay
|
|
39
|
-
delay = delay + jitterValue * (random - 0.5) * 2 // Adjust delay randomly within ±30%
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
return delay
|
|
43
|
-
}
|
package/src/utils/sleep.ts
DELETED
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
export type NonNegativeInteger<T extends number> = number extends T
|
|
2
|
-
? never
|
|
3
|
-
: `${T}` extends `-${string}` | `${string}.${string}`
|
|
4
|
-
? never
|
|
5
|
-
: T
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Pauses execution for a specified number of milliseconds.
|
|
9
|
-
* @param ms The number of milliseconds to pause execution.
|
|
10
|
-
* @returns A promise that resolves after the specified delay.
|
|
11
|
-
*/
|
|
12
|
-
export function sleep(ms: number): Promise<void> {
|
|
13
|
-
if (ms < 0 || !Number.isInteger(ms)) {
|
|
14
|
-
throw new Error('sleep() requires a non-negative integer')
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
return new Promise(resolve => setTimeout(resolve, ms))
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Pauses execution for a specified number of milliseconds.
|
|
22
|
-
* @param ms The number of milliseconds to pause execution.
|
|
23
|
-
* @returns A promise that resolves after the specified delay.
|
|
24
|
-
*/
|
|
25
|
-
export function wait(ms: number): Promise<void> {
|
|
26
|
-
if (ms < 0 || !Number.isInteger(ms)) {
|
|
27
|
-
throw new Error('wait() requires a non-negative integer')
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
return new Promise(resolve => setTimeout(resolve, ms))
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Pauses execution for a specified number of milliseconds.
|
|
35
|
-
* @param ms The number of milliseconds to pause execution.
|
|
36
|
-
* @returns A promise that resolves after the specified delay.
|
|
37
|
-
*/
|
|
38
|
-
export function delay(ms: number): Promise<void> {
|
|
39
|
-
if (ms < 0 || !Number.isInteger(ms)) {
|
|
40
|
-
throw new Error('delay() requires a non-negative integer')
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
return new Promise(resolve => setTimeout(resolve, ms))
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export type WaitOptions = number | {
|
|
47
|
-
interval?: number
|
|
48
|
-
timeout?: number
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Pauses execution until a specified condition is met.
|
|
53
|
-
* @param condition The condition to wait for.
|
|
54
|
-
* @param interval The interval at which to check the condition, in milliseconds. Defaults to 1000.
|
|
55
|
-
* @returns A promise that resolves when the condition is met.
|
|
56
|
-
*/
|
|
57
|
-
export function waitUntil(condition: () => boolean, options: WaitOptions = {}): Promise<void> {
|
|
58
|
-
return new Promise((resolve) => {
|
|
59
|
-
const { interval, timeout } = normalizeOptions(options)
|
|
60
|
-
|
|
61
|
-
// Immediately resolve if the condition is initially true
|
|
62
|
-
if (condition()) {
|
|
63
|
-
resolve()
|
|
64
|
-
return
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
const check = () => {
|
|
68
|
-
if (condition()) {
|
|
69
|
-
resolve()
|
|
70
|
-
}
|
|
71
|
-
else {
|
|
72
|
-
setTimeout(check, interval)
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
if (timeout) {
|
|
77
|
-
setTimeout(resolve, timeout)
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
check()
|
|
81
|
-
})
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
function normalizeOptions(options: WaitOptions): { interval: number, timeout: number } {
|
|
85
|
-
if (typeof options === 'number') {
|
|
86
|
-
return { interval: 100, timeout: options }
|
|
87
|
-
}
|
|
88
|
-
return {
|
|
89
|
-
interval: options.interval ?? 100,
|
|
90
|
-
timeout: options.timeout ?? 0,
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* Pauses execution while a specified condition is met.
|
|
96
|
-
* @param condition The condition to wait while.
|
|
97
|
-
* @param interval The interval at which to check the condition, in milliseconds. Defaults to 1000.
|
|
98
|
-
* @returns A promise that resolves when the condition is no longer met.
|
|
99
|
-
*/
|
|
100
|
-
export function waitWhile(condition: () => boolean, options: WaitOptions = {}): Promise<void> {
|
|
101
|
-
return new Promise((resolve) => {
|
|
102
|
-
const { interval = 100, timeout = 0 } = options
|
|
103
|
-
|
|
104
|
-
// Immediately resolve if the condition is initially false
|
|
105
|
-
if (!condition()) {
|
|
106
|
-
resolve()
|
|
107
|
-
return
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
const check = () => {
|
|
111
|
-
if (!condition()) {
|
|
112
|
-
resolve()
|
|
113
|
-
}
|
|
114
|
-
else {
|
|
115
|
-
setTimeout(check, interval)
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
if (timeout) {
|
|
120
|
-
setTimeout(resolve, timeout)
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
check()
|
|
124
|
-
})
|
|
125
|
-
}
|
package/src/utils/throttle.ts
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Throttle a function.
|
|
3
|
-
*
|
|
4
|
-
* @param {Function} fn - The function to throttle.
|
|
5
|
-
* @param {number} [wait] - The time to wait between function calls.
|
|
6
|
-
* @returns {Function} - A new function that throttles the calls to the original function.
|
|
7
|
-
*
|
|
8
|
-
* @example
|
|
9
|
-
* ```ts
|
|
10
|
-
* // logs window dimensions at most every 250ms
|
|
11
|
-
* window.addEventListener(
|
|
12
|
-
* "resize",
|
|
13
|
-
* throttle(function (evt) {
|
|
14
|
-
* console.log(window.innerWidth)
|
|
15
|
-
* console.log(window.innerHeight)
|
|
16
|
-
* }, 250)
|
|
17
|
-
* )
|
|
18
|
-
* ```
|
|
19
|
-
*/
|
|
20
|
-
// eslint-disable-next-line ts/no-unsafe-function-type
|
|
21
|
-
export function throttle(fn: Function, wait = 300) {
|
|
22
|
-
let inThrottle: boolean
|
|
23
|
-
let lastFn: ReturnType<typeof setTimeout>
|
|
24
|
-
let lastTime: number
|
|
25
|
-
|
|
26
|
-
return function (this: unknown, ...args: any[]): void {
|
|
27
|
-
if (!inThrottle) {
|
|
28
|
-
fn.apply(this, args)
|
|
29
|
-
|
|
30
|
-
lastTime = Date.now()
|
|
31
|
-
inThrottle = true
|
|
32
|
-
}
|
|
33
|
-
else {
|
|
34
|
-
clearTimeout(lastFn)
|
|
35
|
-
|
|
36
|
-
lastFn = setTimeout(
|
|
37
|
-
() => {
|
|
38
|
-
if (Date.now() - lastTime >= wait) {
|
|
39
|
-
fn.apply(this, args) // Use 'this' directly
|
|
40
|
-
lastTime = Date.now()
|
|
41
|
-
}
|
|
42
|
-
},
|
|
43
|
-
Math.max(wait - (Date.now() - lastTime), 0),
|
|
44
|
-
)
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
}
|