run npm install to generate a package lock
This commit is contained in:
10
node_modules/dettle/.editorconfig
generated
vendored
Normal file
10
node_modules/dettle/.editorconfig
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_size = 2
|
||||
indent_style = space
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
3
node_modules/dettle/dist/debounce.d.ts
generated
vendored
Normal file
3
node_modules/dettle/dist/debounce.d.ts
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
import type { FN, DebounceOptions, Debounced } from './types.js';
|
||||
declare const debounce: <Args extends unknown[]>(fn: FN<Args, unknown>, wait?: number, options?: DebounceOptions) => Debounced<Args>;
|
||||
export default debounce;
|
||||
91
node_modules/dettle/dist/debounce.js
generated
vendored
Normal file
91
node_modules/dettle/dist/debounce.js
generated
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
/* IMPORT */
|
||||
/* MAIN */
|
||||
const debounce = (fn, wait = 1, options) => {
|
||||
/* VARIABLES */
|
||||
wait = Math.max(1, wait);
|
||||
const leading = options?.leading ?? false;
|
||||
const trailing = options?.trailing ?? true;
|
||||
const maxWait = Math.max(options?.maxWait ?? Infinity, wait);
|
||||
let args;
|
||||
let timeout;
|
||||
let timestampCall = 0;
|
||||
let timestampInvoke = 0;
|
||||
/* HELPERS */
|
||||
const getInstantData = () => {
|
||||
const timestamp = Date.now();
|
||||
const elapsedCall = timestamp - timestampCall;
|
||||
const elapsedInvoke = timestamp - timestampInvoke;
|
||||
const isInvoke = (elapsedCall >= wait || elapsedInvoke >= maxWait);
|
||||
return [timestamp, isInvoke];
|
||||
};
|
||||
const invoke = (timestamp) => {
|
||||
timestampInvoke = timestamp;
|
||||
if (!args)
|
||||
return; // This should never happen
|
||||
const _args = args;
|
||||
args = undefined;
|
||||
fn.apply(undefined, _args);
|
||||
};
|
||||
const onCancel = () => {
|
||||
resetTimeout(0);
|
||||
};
|
||||
const onFlush = () => {
|
||||
if (!timeout)
|
||||
return;
|
||||
onCancel();
|
||||
invoke(Date.now());
|
||||
};
|
||||
const onLeading = (timestamp) => {
|
||||
timestampInvoke = timestamp;
|
||||
if (leading)
|
||||
return invoke(timestamp);
|
||||
};
|
||||
const onTrailing = (timestamp) => {
|
||||
if (trailing && args)
|
||||
return invoke(timestamp);
|
||||
args = undefined;
|
||||
};
|
||||
const onTimeout = () => {
|
||||
timeout = undefined;
|
||||
const [timestamp, isInvoking] = getInstantData();
|
||||
if (isInvoking)
|
||||
return onTrailing(timestamp);
|
||||
return updateTimeout(timestamp);
|
||||
};
|
||||
const updateTimeout = (timestamp) => {
|
||||
const elapsedCall = timestamp - timestampCall;
|
||||
const elapsedInvoke = timestamp - timestampInvoke;
|
||||
const remainingCall = wait - elapsedCall;
|
||||
const remainingInvoke = maxWait - elapsedInvoke;
|
||||
const ms = Math.min(remainingCall, remainingInvoke);
|
||||
return resetTimeout(ms);
|
||||
};
|
||||
const resetTimeout = (ms) => {
|
||||
if (timeout)
|
||||
clearTimeout(timeout);
|
||||
if (ms <= 0)
|
||||
return;
|
||||
timeout = setTimeout(onTimeout, ms);
|
||||
};
|
||||
/* DEBOUNCED */
|
||||
const debounced = (...argsLatest) => {
|
||||
const [timestamp, isInvoking] = getInstantData();
|
||||
const hadTimeout = !!timeout;
|
||||
args = argsLatest;
|
||||
timestampCall = timestamp;
|
||||
if (isInvoking || !timeout)
|
||||
resetTimeout(wait);
|
||||
if (isInvoking) {
|
||||
if (!hadTimeout)
|
||||
return onLeading(timestamp);
|
||||
return invoke(timestamp);
|
||||
}
|
||||
};
|
||||
/* DEBOUNCED UTILITIES */
|
||||
debounced.cancel = onCancel;
|
||||
debounced.flush = onFlush;
|
||||
/* RETURN */
|
||||
return debounced;
|
||||
};
|
||||
/* EXPORT */
|
||||
export default debounce;
|
||||
5
node_modules/dettle/dist/index.d.ts
generated
vendored
Normal file
5
node_modules/dettle/dist/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
import debounce from './debounce.js';
|
||||
import throttle from './throttle.js';
|
||||
import type { DebounceOptions, Debounced, ThrottleOptions, Throttled } from './types.js';
|
||||
export { debounce, throttle };
|
||||
export type { DebounceOptions, Debounced, ThrottleOptions, Throttled };
|
||||
5
node_modules/dettle/dist/index.js
generated
vendored
Normal file
5
node_modules/dettle/dist/index.js
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
/* IMPORT */
|
||||
import debounce from './debounce.js';
|
||||
import throttle from './throttle.js';
|
||||
/* EXPORT */
|
||||
export { debounce, throttle };
|
||||
3
node_modules/dettle/dist/throttle.d.ts
generated
vendored
Normal file
3
node_modules/dettle/dist/throttle.d.ts
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
import type { FN, ThrottleOptions, Throttled } from './types.js';
|
||||
declare const throttle: <Args extends unknown[]>(fn: FN<Args, unknown>, wait?: number, options?: ThrottleOptions) => Throttled<Args>;
|
||||
export default throttle;
|
||||
12
node_modules/dettle/dist/throttle.js
generated
vendored
Normal file
12
node_modules/dettle/dist/throttle.js
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
/* IMPORT */
|
||||
import debounce from './debounce.js';
|
||||
/* MAIN */
|
||||
const throttle = (fn, wait = 1, options) => {
|
||||
return debounce(fn, wait, {
|
||||
leading: options?.leading ?? true,
|
||||
trailing: options?.trailing ?? true,
|
||||
maxWait: wait
|
||||
});
|
||||
};
|
||||
/* EXPORT */
|
||||
export default throttle;
|
||||
20
node_modules/dettle/dist/types.d.ts
generated
vendored
Normal file
20
node_modules/dettle/dist/types.d.ts
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
type Callback = () => void;
|
||||
type FN<Args extends unknown[], Return> = (...args: Args) => Return;
|
||||
type DebounceOptions = {
|
||||
leading?: boolean;
|
||||
trailing?: boolean;
|
||||
maxWait?: number;
|
||||
};
|
||||
type Debounced<Args extends unknown[]> = FN<Args, void> & {
|
||||
cancel: Callback;
|
||||
flush: Callback;
|
||||
};
|
||||
type ThrottleOptions = {
|
||||
leading?: boolean;
|
||||
trailing?: boolean;
|
||||
};
|
||||
type Throttled<Args extends unknown[]> = FN<Args, void> & {
|
||||
cancel: Callback;
|
||||
flush: Callback;
|
||||
};
|
||||
export type { Callback, FN, DebounceOptions, Debounced, ThrottleOptions, Throttled };
|
||||
2
node_modules/dettle/dist/types.js
generated
vendored
Normal file
2
node_modules/dettle/dist/types.js
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
/* MAIN */
|
||||
export {};
|
||||
21
node_modules/dettle/license
generated
vendored
Normal file
21
node_modules/dettle/license
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2023-present Fabio Spampinato
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
28
node_modules/dettle/package.json
generated
vendored
Executable file
28
node_modules/dettle/package.json
generated
vendored
Executable file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"name": "dettle",
|
||||
"repository": "github:fabiospampinato/dettle",
|
||||
"description": "A tiny fully-featured debounce and throttle implementation.",
|
||||
"version": "1.0.4",
|
||||
"type": "module",
|
||||
"main": "dist/index.js",
|
||||
"exports": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
"scripts": {
|
||||
"clean": "tsex clean",
|
||||
"compile": "tsex compile",
|
||||
"compile:watch": "tsex compile --watch",
|
||||
"test": "tsex test",
|
||||
"test:watch": "tsex test --watch",
|
||||
"prepublishOnly": "tsex prepare"
|
||||
},
|
||||
"keywords": [
|
||||
"tiny",
|
||||
"debounce",
|
||||
"throttle"
|
||||
],
|
||||
"devDependencies": {
|
||||
"fava": "^0.3.4",
|
||||
"tsex": "^4.0.2",
|
||||
"typescript": "^5.5.2"
|
||||
}
|
||||
}
|
||||
55
node_modules/dettle/readme.md
generated
vendored
Normal file
55
node_modules/dettle/readme.md
generated
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
# Dettle
|
||||
|
||||
A tiny fully-featured debounce and throttle implementation.
|
||||
|
||||
## Install
|
||||
|
||||
```sh
|
||||
npm install --save dettle
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```ts
|
||||
import {debounce, throttle} from 'dettle';
|
||||
|
||||
const fn = () => console.log ( 'Fired!' );
|
||||
|
||||
// Debouncing
|
||||
// The following options are supported:
|
||||
// `leading`: whether the function should be called when the timeout is created, defaults to `false`
|
||||
// `trailing`: whether the function should be called when the timeout expires, defaults to `true`
|
||||
// `maxWait`: the maximum amount of time that can pass before the function is called, defaults to `Infinity`
|
||||
|
||||
const debounced = debounce ( fn, 1000, {
|
||||
leading: false,
|
||||
trailing: true,
|
||||
maxWait: Infinity
|
||||
});
|
||||
|
||||
debounced (); // Schedule function for execution
|
||||
debounced (); // Re-schedule function for execution
|
||||
|
||||
debounced.flush (); // Execute the function immediately, if there's a scheduled execution
|
||||
debounced.cancel (); // Cancel the scheduled execution
|
||||
|
||||
// Throttling
|
||||
// The API for throttling is basically the same, except that:
|
||||
// - `leading`: is `true` by default rather than `false`
|
||||
// - `maxWait`: is set implicitly for you to be equal to the wait time
|
||||
|
||||
const throttled = throttle ( fn, 1000, {
|
||||
leading: true,
|
||||
trailing: true
|
||||
});
|
||||
|
||||
throttled (); // Call the function immediately
|
||||
throttled (); // Schedule function for execution
|
||||
|
||||
throttled.flush (); // Execute the function immediately, if there's a scheduled execution
|
||||
throttled.cancel (); // Cancel the scheduled execution
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT © Fabio Spampinato
|
||||
152
node_modules/dettle/src/debounce.ts
generated
vendored
Normal file
152
node_modules/dettle/src/debounce.ts
generated
vendored
Normal file
@@ -0,0 +1,152 @@
|
||||
|
||||
/* IMPORT */
|
||||
|
||||
import type {FN, DebounceOptions, Debounced} from './types';
|
||||
|
||||
/* MAIN */
|
||||
|
||||
const debounce = <Args extends unknown[]> ( fn: FN<Args, unknown>, wait: number = 1, options?: DebounceOptions ): Debounced<Args> => {
|
||||
|
||||
/* VARIABLES */
|
||||
|
||||
wait = Math.max ( 1, wait );
|
||||
|
||||
const leading = options?.leading ?? false;
|
||||
const trailing = options?.trailing ?? true;
|
||||
const maxWait = Math.max ( options?.maxWait ?? Infinity, wait );
|
||||
|
||||
let args: Args | undefined;
|
||||
let timeout: ReturnType<typeof setTimeout> | undefined;
|
||||
let timestampCall = 0;
|
||||
let timestampInvoke = 0;
|
||||
|
||||
/* HELPERS */
|
||||
|
||||
const getInstantData = (): [number, boolean] => {
|
||||
|
||||
const timestamp = Date.now ();
|
||||
const elapsedCall = timestamp - timestampCall;
|
||||
const elapsedInvoke = timestamp - timestampInvoke;
|
||||
const isInvoke = ( elapsedCall >= wait || elapsedInvoke >= maxWait );
|
||||
|
||||
return [timestamp, isInvoke];
|
||||
|
||||
};
|
||||
|
||||
const invoke = ( timestamp: number ): void => {
|
||||
|
||||
timestampInvoke = timestamp;
|
||||
|
||||
if ( !args ) return; // This should never happen
|
||||
|
||||
const _args = args;
|
||||
|
||||
args = undefined;
|
||||
|
||||
fn.apply ( undefined, _args );
|
||||
|
||||
};
|
||||
|
||||
const onCancel = (): void => {
|
||||
|
||||
resetTimeout ( 0 );
|
||||
|
||||
};
|
||||
|
||||
const onFlush = (): void => {
|
||||
|
||||
if ( !timeout ) return;
|
||||
|
||||
onCancel ();
|
||||
|
||||
invoke ( Date.now () );
|
||||
|
||||
};
|
||||
|
||||
const onLeading = ( timestamp: number ): void => {
|
||||
|
||||
timestampInvoke = timestamp;
|
||||
|
||||
if ( leading ) return invoke ( timestamp );
|
||||
|
||||
};
|
||||
|
||||
const onTrailing = ( timestamp: number ): void => {
|
||||
|
||||
if ( trailing && args ) return invoke ( timestamp );
|
||||
|
||||
args = undefined;
|
||||
|
||||
};
|
||||
|
||||
const onTimeout = (): void => {
|
||||
|
||||
timeout = undefined;
|
||||
|
||||
const [timestamp, isInvoking] = getInstantData ();
|
||||
|
||||
if ( isInvoking ) return onTrailing ( timestamp );
|
||||
|
||||
return updateTimeout ( timestamp );
|
||||
|
||||
};
|
||||
|
||||
const updateTimeout = ( timestamp: number ): void => {
|
||||
|
||||
const elapsedCall = timestamp - timestampCall;
|
||||
const elapsedInvoke = timestamp - timestampInvoke;
|
||||
const remainingCall = wait - elapsedCall;
|
||||
const remainingInvoke = maxWait - elapsedInvoke;
|
||||
const ms = Math.min ( remainingCall, remainingInvoke );
|
||||
|
||||
return resetTimeout ( ms );
|
||||
|
||||
};
|
||||
|
||||
const resetTimeout = ( ms: number ): void => {
|
||||
|
||||
if ( timeout ) clearTimeout ( timeout );
|
||||
|
||||
if ( ms <= 0 ) return;
|
||||
|
||||
timeout = setTimeout ( onTimeout, ms );
|
||||
|
||||
};
|
||||
|
||||
/* DEBOUNCED */
|
||||
|
||||
const debounced = ( ...argsLatest: Args ): void => {
|
||||
|
||||
const [timestamp, isInvoking] = getInstantData ();
|
||||
const hadTimeout = !!timeout;
|
||||
|
||||
args = argsLatest;
|
||||
timestampCall = timestamp;
|
||||
|
||||
if ( isInvoking || !timeout ) resetTimeout ( wait );
|
||||
|
||||
if ( isInvoking ) {
|
||||
|
||||
if ( !hadTimeout ) return onLeading ( timestamp );
|
||||
|
||||
return invoke ( timestamp );
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/* DEBOUNCED UTILITIES */
|
||||
|
||||
debounced.cancel = onCancel;
|
||||
|
||||
debounced.flush = onFlush;
|
||||
|
||||
/* RETURN */
|
||||
|
||||
return debounced;
|
||||
|
||||
};
|
||||
|
||||
/* EXPORT */
|
||||
|
||||
export default debounce;
|
||||
11
node_modules/dettle/src/index.ts
generated
vendored
Executable file
11
node_modules/dettle/src/index.ts
generated
vendored
Executable file
@@ -0,0 +1,11 @@
|
||||
|
||||
/* IMPORT */
|
||||
|
||||
import debounce from './debounce';
|
||||
import throttle from './throttle';
|
||||
import type {DebounceOptions, Debounced, ThrottleOptions, Throttled} from './types';
|
||||
|
||||
/* EXPORT */
|
||||
|
||||
export {debounce, throttle};
|
||||
export type {DebounceOptions, Debounced, ThrottleOptions, Throttled};
|
||||
21
node_modules/dettle/src/throttle.ts
generated
vendored
Normal file
21
node_modules/dettle/src/throttle.ts
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
|
||||
/* IMPORT */
|
||||
|
||||
import debounce from './debounce';
|
||||
import type {FN, ThrottleOptions, Throttled} from './types';
|
||||
|
||||
/* MAIN */
|
||||
|
||||
const throttle = <Args extends unknown[]> ( fn: FN<Args, unknown>, wait: number = 1, options?: ThrottleOptions ): Throttled<Args> => {
|
||||
|
||||
return debounce ( fn, wait, {
|
||||
leading: options?.leading ?? true,
|
||||
trailing: options?.trailing ?? true,
|
||||
maxWait: wait
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
/* EXPORT */
|
||||
|
||||
export default throttle;
|
||||
18
node_modules/dettle/src/types.ts
generated
vendored
Normal file
18
node_modules/dettle/src/types.ts
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
|
||||
/* MAIN */
|
||||
|
||||
type Callback = () => void;
|
||||
|
||||
type FN<Args extends unknown[], Return> = ( ...args: Args ) => Return;
|
||||
|
||||
type DebounceOptions = { leading?: boolean, trailing?: boolean, maxWait?: number };
|
||||
|
||||
type Debounced<Args extends unknown[]> = FN<Args, void> & { cancel: Callback, flush: Callback };
|
||||
|
||||
type ThrottleOptions = { leading?: boolean, trailing?: boolean };
|
||||
|
||||
type Throttled<Args extends unknown[]> = FN<Args, void> & { cancel: Callback, flush: Callback };
|
||||
|
||||
/* EXPORT */
|
||||
|
||||
export type {Callback, FN, DebounceOptions, Debounced, ThrottleOptions, Throttled};
|
||||
87
node_modules/dettle/test/index.js
generated
vendored
Normal file
87
node_modules/dettle/test/index.js
generated
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
|
||||
/* IMPORT */
|
||||
|
||||
import {describe} from 'fava';
|
||||
import {debounce, throttle} from '../dist/index.js';
|
||||
|
||||
/* MAIN */
|
||||
|
||||
describe ( 'Dettle', () => {
|
||||
|
||||
describe ( 'debounce', it => {
|
||||
|
||||
it ( 'debounces function execution', async t => {
|
||||
|
||||
let count = 0;
|
||||
let fn = () => count++;
|
||||
let dfn = debounce ( fn, 100 );
|
||||
|
||||
for ( let i = 0; i < 1000; i++ ) {
|
||||
|
||||
dfn ();
|
||||
|
||||
await t.wait ( 1 );
|
||||
|
||||
}
|
||||
|
||||
await t.wait ( 500 );
|
||||
|
||||
t.is ( count, 1 );
|
||||
|
||||
});
|
||||
|
||||
it ( 'works with a 0 delay', async t => {
|
||||
|
||||
let count = 0;
|
||||
let fn = () => count++;
|
||||
let dfn = debounce ( fn, 0 );
|
||||
|
||||
dfn ();
|
||||
|
||||
await t.wait ( 5 );
|
||||
|
||||
t.is ( count, 1 );
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe ( 'throttle', it => {
|
||||
|
||||
it ( 'throttles function execution', async t => {
|
||||
|
||||
let count = 0;
|
||||
let fn = () => count++;
|
||||
let tfn = throttle ( fn, 100 );
|
||||
|
||||
for ( let i = 0; i < 1000; i++ ) {
|
||||
|
||||
tfn ();
|
||||
|
||||
await t.wait ( 1 );
|
||||
|
||||
}
|
||||
|
||||
await t.wait ( 500 );
|
||||
|
||||
t.true ( count > 10 );
|
||||
|
||||
});
|
||||
|
||||
it ( 'works with a 0 delay', async t => {
|
||||
|
||||
let count = 0;
|
||||
let fn = () => count++;
|
||||
let tfn = throttle ( fn, 0 );
|
||||
|
||||
tfn ();
|
||||
|
||||
await t.wait ( 5 );
|
||||
|
||||
t.is ( count, 1 );
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
3
node_modules/dettle/tsconfig.json
generated
vendored
Executable file
3
node_modules/dettle/tsconfig.json
generated
vendored
Executable file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"extends": "tsex/tsconfig.json"
|
||||
}
|
||||
Reference in New Issue
Block a user