kontroll 1.1.3 → 1.2.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.d.mts +41 -41
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +176 -1
- package/dist/index.mjs.map +1 -0
- package/package.json +7 -7
- package/dist/index.d.ts +0 -159
package/dist/index.d.mts
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
|
+
//#region src/index.d.ts
|
|
1
2
|
type Fn<T = void> = () => T;
|
|
2
3
|
type FnWithArgs<T = void> = (...args: any) => T;
|
|
3
|
-
interface KontrollStore {
|
|
4
|
-
|
|
4
|
+
export interface KontrollStore {
|
|
5
|
+
[x: PropertyKey]: KontrollInstance;
|
|
5
6
|
}
|
|
6
|
-
interface KontrollInstance {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
export interface KontrollInstance {
|
|
8
|
+
timer: ReturnType<typeof setTimeout>;
|
|
9
|
+
callback: Fn<any | Promise<any>>;
|
|
10
|
+
trailing?: [FnWithArgs, ...any];
|
|
11
|
+
finishing?: boolean;
|
|
11
12
|
}
|
|
12
|
-
declare function clear(callback: Fn): void;
|
|
13
|
-
declare function clear(key: keyof KontrollStore): void;
|
|
13
|
+
export declare function clear(callback: Fn): void;
|
|
14
|
+
export declare function clear(key: keyof KontrollStore): void;
|
|
14
15
|
/**
|
|
15
16
|
* Returns the {@link KontrollInstance} for the given key, if exists.
|
|
16
17
|
*
|
|
@@ -26,21 +27,21 @@ declare function clear(key: keyof KontrollStore): void;
|
|
|
26
27
|
* // Result: `KontrollInstance` ({ timer: Timeout, callback: <fn>, finishing: true })
|
|
27
28
|
* ```
|
|
28
29
|
*/
|
|
29
|
-
declare function getInstance(key: keyof KontrollStore): KontrollInstance | undefined;
|
|
30
|
-
type KontrollClearer = Fn;
|
|
31
|
-
interface KontrollBaseOptions {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
30
|
+
export declare function getInstance(key: keyof KontrollStore): KontrollInstance | undefined;
|
|
31
|
+
export type KontrollClearer = Fn;
|
|
32
|
+
export interface KontrollBaseOptions {
|
|
33
|
+
/**
|
|
34
|
+
* Specify a known key if needed
|
|
35
|
+
* @default string // .toString() of the inputted callback
|
|
36
|
+
*/
|
|
37
|
+
key?: keyof KontrollStore;
|
|
37
38
|
}
|
|
38
|
-
interface KontrollCountdownOptions extends KontrollBaseOptions {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
39
|
+
export interface KontrollCountdownOptions extends KontrollBaseOptions {
|
|
40
|
+
/**
|
|
41
|
+
* Replaces the current timed callback
|
|
42
|
+
* @default false
|
|
43
|
+
*/
|
|
44
|
+
replace?: boolean;
|
|
44
45
|
}
|
|
45
46
|
/**
|
|
46
47
|
* Countdown for a period of ms then execute the first/replaced callback, based on `options.replace`.
|
|
@@ -69,13 +70,13 @@ interface KontrollCountdownOptions extends KontrollBaseOptions {
|
|
|
69
70
|
* // Result: 2
|
|
70
71
|
* ```
|
|
71
72
|
*/
|
|
72
|
-
declare function countdown(ms: number, callback: Fn, { key, replace }?: KontrollCountdownOptions): KontrollClearer;
|
|
73
|
-
interface KontrollDebounceOptions extends KontrollBaseOptions {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
73
|
+
export declare function countdown(ms: number, callback: Fn, { key, replace }?: KontrollCountdownOptions): KontrollClearer;
|
|
74
|
+
export interface KontrollDebounceOptions extends KontrollBaseOptions {
|
|
75
|
+
/**
|
|
76
|
+
* Avoiding initial wait for first call
|
|
77
|
+
* @default false
|
|
78
|
+
*/
|
|
79
|
+
leading?: boolean;
|
|
79
80
|
}
|
|
80
81
|
/**
|
|
81
82
|
* Creates a timer that will execute the callback upon finish, calls while the timer haven't finished recreates the timer.
|
|
@@ -107,13 +108,13 @@ interface KontrollDebounceOptions extends KontrollBaseOptions {
|
|
|
107
108
|
* // Result: 3
|
|
108
109
|
* ```
|
|
109
110
|
*/
|
|
110
|
-
declare function debounce(ms: number, callback: Fn, { key, leading }?: KontrollDebounceOptions): KontrollClearer;
|
|
111
|
-
interface KontrollThrottleOptions extends KontrollBaseOptions {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
111
|
+
export declare function debounce(ms: number, callback: Fn, { key, leading }?: KontrollDebounceOptions): KontrollClearer;
|
|
112
|
+
export interface KontrollThrottleOptions extends KontrollBaseOptions {
|
|
113
|
+
/**
|
|
114
|
+
* Perform additional execution with last received arguments
|
|
115
|
+
* @default false
|
|
116
|
+
*/
|
|
117
|
+
trailing?: boolean;
|
|
117
118
|
}
|
|
118
119
|
/**
|
|
119
120
|
* Executes the callback, and bypass any subsequent calls for a period of ms.
|
|
@@ -153,7 +154,6 @@ interface KontrollThrottleOptions extends KontrollBaseOptions {
|
|
|
153
154
|
* ```
|
|
154
155
|
*
|
|
155
156
|
*/
|
|
156
|
-
declare function throttle(ms: number, callback: Fn, { key, trailing }?: KontrollThrottleOptions): KontrollClearer;
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
export type { KontrollBaseOptions, KontrollClearer, KontrollCountdownOptions, KontrollDebounceOptions, KontrollInstance, KontrollStore, KontrollThrottleOptions };
|
|
157
|
+
export declare function throttle(ms: number, callback: Fn, { key, trailing }?: KontrollThrottleOptions): KontrollClearer;
|
|
158
|
+
//#endregion
|
|
159
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/index.ts"],"mappings":";KAAK,GAAG,kBAAkB;KACrB,WAAW,gBAAgB,cAAc;iBAE7B;GACd,GAAG,cAAc;;iBAGH;EACf,OAAO,kBAAkB;EACzB,UAAU,SAAS;EACnB,YAAY;EACZ;;wBAKc,MAAM,UAAU;wBAChB,MAAM,WAAW;;;;;;;;;;;;;;;;wBAwBjB,YAAY,WAAW,gBAAgB;YAI3C,kBAAkB;iBAqCb;;;;;EAKf,YAAY;;iBAGG,iCAAiC;;;;;EAKhD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBA6Bc,UAAU,YAAY,UAAU,MAAM,KAA2B,YAAW,2BAA6B;iBAWxG,gCAAgC;;;;;EAK/C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAgCc,SAAS,YAAY,UAAU,MAAM,KAA2B,YAAW,0BAA4B;iBAWtG,gCAAgC;;;;;EAK/C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAwCc,SAAS,YAAY,UAAU,MAAM,KAA2B,aAAY,0BAA4B"}
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1,176 @@
|
|
|
1
|
-
|
|
1
|
+
//#region src/index.ts
|
|
2
|
+
const keyStore = {};
|
|
3
|
+
function clear(keyable) {
|
|
4
|
+
const key = typeof keyable === "function" ? keyable.toString() : keyable;
|
|
5
|
+
if (keyStore[key]) {
|
|
6
|
+
clearTimeout(keyStore[key].timer);
|
|
7
|
+
delete keyStore[key];
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Returns the {@link KontrollInstance} for the given key, if exists.
|
|
12
|
+
*
|
|
13
|
+
* Could be useful to check if a promise is executing and not settled.
|
|
14
|
+
*
|
|
15
|
+
* ---
|
|
16
|
+
*
|
|
17
|
+
* Example
|
|
18
|
+
* ```
|
|
19
|
+
* debounce(1, async => await sleep(1000), { key: '1sec' })
|
|
20
|
+
* // 500ms passed
|
|
21
|
+
* getInstance('1sec')
|
|
22
|
+
* // Result: `KontrollInstance` ({ timer: Timeout, callback: <fn>, finishing: true })
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
function getInstance(key) {
|
|
26
|
+
return keyStore[key];
|
|
27
|
+
}
|
|
28
|
+
function createClearFn(key) {
|
|
29
|
+
return () => {
|
|
30
|
+
clear(key);
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
async function finish(key) {
|
|
34
|
+
if (keyStore[key]) {
|
|
35
|
+
keyStore[key].finishing = true;
|
|
36
|
+
const trailing = keyStore[key].trailing;
|
|
37
|
+
await keyStore[key].callback();
|
|
38
|
+
clear(key);
|
|
39
|
+
if (trailing) trailing[0](...trailing.slice(1));
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function createTimeout(ms, callback, key) {
|
|
43
|
+
if (keyStore[key]?.finishing) return createClearFn(key);
|
|
44
|
+
const timer = setTimeout(() => {
|
|
45
|
+
finish(key);
|
|
46
|
+
}, ms);
|
|
47
|
+
keyStore[key] = {
|
|
48
|
+
timer,
|
|
49
|
+
callback
|
|
50
|
+
};
|
|
51
|
+
return createClearFn(key);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Countdown for a period of ms then execute the first/replaced callback, based on `options.replace`.
|
|
55
|
+
*
|
|
56
|
+
* Calls while the timer haven't finished are dropped.
|
|
57
|
+
*
|
|
58
|
+
* ---
|
|
59
|
+
*
|
|
60
|
+
* Example
|
|
61
|
+
* ```
|
|
62
|
+
* countdown(1000, doSum(1), { key: 'eg' })
|
|
63
|
+
* // 500ms passed
|
|
64
|
+
* countdown(1000, doSum(2))
|
|
65
|
+
* // 500ms passed
|
|
66
|
+
* // Result: 1
|
|
67
|
+
* ```
|
|
68
|
+
*
|
|
69
|
+
* ---
|
|
70
|
+
*
|
|
71
|
+
* Example with `options.replace=true`:
|
|
72
|
+
* ```
|
|
73
|
+
* countdown(1000, doSum(1))
|
|
74
|
+
* // 500ms passed
|
|
75
|
+
* countdown(1000, doSum(2), { replace: true })
|
|
76
|
+
* // 500ms passed
|
|
77
|
+
* // Result: 2
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
80
|
+
function countdown(ms, callback, { key = callback.toString(), replace } = {}) {
|
|
81
|
+
if (keyStore[key]) {
|
|
82
|
+
if (replace) keyStore[key].callback = callback;
|
|
83
|
+
return createClearFn(key);
|
|
84
|
+
}
|
|
85
|
+
return createTimeout(ms, callback, key);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Creates a timer that will execute the callback upon finish, calls while the timer haven't finished recreates the timer.
|
|
89
|
+
*
|
|
90
|
+
* If `options.leading`, execute callback immediately for initial call.
|
|
91
|
+
*
|
|
92
|
+
* ---
|
|
93
|
+
*
|
|
94
|
+
* Example:
|
|
95
|
+
* ```
|
|
96
|
+
* debounce(1000, doSum(1))
|
|
97
|
+
* // 500ms passed
|
|
98
|
+
* debounce(1000, doSum(2))
|
|
99
|
+
* // 1000ms passed
|
|
100
|
+
* // Result: 2
|
|
101
|
+
* ```
|
|
102
|
+
*
|
|
103
|
+
* ---
|
|
104
|
+
*
|
|
105
|
+
* Example with `options.leading`:
|
|
106
|
+
* ```
|
|
107
|
+
* debounce(1000, doSum(1), { leading: true })
|
|
108
|
+
* // Result: 1
|
|
109
|
+
* // 500ms passed
|
|
110
|
+
* debounce(1000, doSum(2), { leading: true }) // leading doesn't matter anymore in this timer scope
|
|
111
|
+
* // 500ms passed
|
|
112
|
+
* debounce(1000, doSum(3))
|
|
113
|
+
* // 1000ms passed
|
|
114
|
+
* // Result: 3
|
|
115
|
+
* ```
|
|
116
|
+
*/
|
|
117
|
+
function debounce(ms, callback, { key = callback.toString(), leading } = {}) {
|
|
118
|
+
if (keyStore[key] && !keyStore[key].finishing) clear(key);
|
|
119
|
+
else if (leading) return throttle(ms, callback, { key });
|
|
120
|
+
return createTimeout(ms, callback, key);
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Executes the callback, and bypass any subsequent calls for a period of ms.
|
|
124
|
+
*
|
|
125
|
+
* Calls while the timer haven't finished are dropped.
|
|
126
|
+
*
|
|
127
|
+
* If `options.trailing` and calls while the timer haven't finished are received,
|
|
128
|
+
*
|
|
129
|
+
* an additional execution with last received arguments is performed.
|
|
130
|
+
*
|
|
131
|
+
* ---
|
|
132
|
+
*
|
|
133
|
+
* Example:
|
|
134
|
+
* ```
|
|
135
|
+
* throttle(1000, doSum(1))
|
|
136
|
+
* // Result: 1
|
|
137
|
+
* // 500ms passed
|
|
138
|
+
* throttle(1000, doSum(2))
|
|
139
|
+
* // 9999ms passed
|
|
140
|
+
* // (Nothing)
|
|
141
|
+
* ```
|
|
142
|
+
*
|
|
143
|
+
* ---
|
|
144
|
+
*
|
|
145
|
+
* Example with `options.trailing`:
|
|
146
|
+
* ```
|
|
147
|
+
* throttle(1000, doSum(1))
|
|
148
|
+
* // Result: 1
|
|
149
|
+
* // 500ms passed
|
|
150
|
+
* throttle(1000, doSum(2), { trailing: true })
|
|
151
|
+
* // 500ms passed
|
|
152
|
+
* // Result: 2
|
|
153
|
+
* // A timer is also created, so calls after that are still dropped:
|
|
154
|
+
* throttle(1000, doSum(3))
|
|
155
|
+
* // 9999ms passed
|
|
156
|
+
* // (Nothing)
|
|
157
|
+
* ```
|
|
158
|
+
*
|
|
159
|
+
*/
|
|
160
|
+
function throttle(ms, callback, { key = callback.toString(), trailing } = {}) {
|
|
161
|
+
if (keyStore[key]) {
|
|
162
|
+
if (trailing) keyStore[key].trailing = [
|
|
163
|
+
throttle,
|
|
164
|
+
ms,
|
|
165
|
+
callback,
|
|
166
|
+
{ key }
|
|
167
|
+
];
|
|
168
|
+
return createClearFn(key);
|
|
169
|
+
}
|
|
170
|
+
const r = callback();
|
|
171
|
+
return createTimeout(ms, () => r, key);
|
|
172
|
+
}
|
|
173
|
+
//#endregion
|
|
174
|
+
export { clear, countdown, debounce, getInstance, throttle };
|
|
175
|
+
|
|
176
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["type Fn<T = void> = () => T\ntype FnWithArgs<T = void> = (...args: any) => T\n\nexport interface KontrollStore {\n [x: PropertyKey]: KontrollInstance\n}\n\nexport interface KontrollInstance {\n timer: ReturnType<typeof setTimeout>\n callback: Fn<any | Promise<any>>\n trailing?: [FnWithArgs, ...any]\n finishing?: boolean\n}\n\nconst keyStore: KontrollStore = {}\n\nexport function clear(callback: Fn): void\nexport function clear(key: keyof KontrollStore): void\nexport function clear(keyable: Fn | keyof KontrollStore) {\n const key = typeof keyable === 'function' ? keyable.toString() : keyable\n if (keyStore[key]) {\n clearTimeout(keyStore[key].timer)\n delete keyStore[key]\n }\n}\n\n/**\n * Returns the {@link KontrollInstance} for the given key, if exists.\n * \n * Could be useful to check if a promise is executing and not settled.\n * \n * ---\n * \n * Example\n * ```\n * debounce(1, async => await sleep(1000), { key: '1sec' })\n * // 500ms passed\n * getInstance('1sec')\n * // Result: `KontrollInstance` ({ timer: Timeout, callback: <fn>, finishing: true })\n * ```\n */\nexport function getInstance(key: keyof KontrollStore): KontrollInstance | undefined {\n return keyStore[key]\n}\n\nexport type KontrollClearer = Fn\nfunction createClearFn(key: keyof KontrollStore): KontrollClearer {\n return () => { clear(key) }\n}\n\nasync function finish(key: keyof KontrollStore) {\n if (keyStore[key]) {\n keyStore[key].finishing = true\n const trailing = keyStore[key].trailing\n\n await keyStore[key].callback()\n\n clear(key)\n\n if (trailing)\n trailing[0](...trailing.slice(1))\n }\n}\n\nfunction createTimeout(ms: number, callback: Fn, key: keyof KontrollStore) {\n if (keyStore[key]?.finishing)\n return createClearFn(key)\n\n const timer = setTimeout(\n () => { finish(key) },\n ms,\n )\n\n keyStore[key] = {\n timer,\n callback,\n }\n\n return createClearFn(key)\n}\n\n// TODO: do .toString() have big performance overhead?, maybe implements a WeakMap?\nexport interface KontrollBaseOptions {\n /**\n * Specify a known key if needed\n * @default string // .toString() of the inputted callback\n */\n key?: keyof KontrollStore\n}\n\nexport interface KontrollCountdownOptions extends KontrollBaseOptions {\n /**\n * Replaces the current timed callback\n * @default false\n */\n replace?: boolean\n}\n/**\n * Countdown for a period of ms then execute the first/replaced callback, based on `options.replace`.\n * \n * Calls while the timer haven't finished are dropped.\n * \n * ---\n * \n * Example\n * ```\n * countdown(1000, doSum(1), { key: 'eg' })\n * // 500ms passed\n * countdown(1000, doSum(2))\n * // 500ms passed\n * // Result: 1\n * ```\n * \n * ---\n * \n * Example with `options.replace=true`:\n * ```\n * countdown(1000, doSum(1))\n * // 500ms passed\n * countdown(1000, doSum(2), { replace: true })\n * // 500ms passed\n * // Result: 2\n * ```\n */\nexport function countdown(ms: number, callback: Fn, { key = callback.toString(), replace }: KontrollCountdownOptions = {}) {\n if (keyStore[key]) {\n if (replace)\n keyStore[key].callback = callback\n\n return createClearFn(key)\n }\n\n return createTimeout(ms, callback, key)\n}\n\nexport interface KontrollDebounceOptions extends KontrollBaseOptions {\n /**\n * Avoiding initial wait for first call\n * @default false\n */\n leading?: boolean\n}\n/**\n * Creates a timer that will execute the callback upon finish, calls while the timer haven't finished recreates the timer.\n * \n * If `options.leading`, execute callback immediately for initial call.\n * \n * ---\n * \n * Example:\n * ```\n * debounce(1000, doSum(1))\n * // 500ms passed\n * debounce(1000, doSum(2))\n * // 1000ms passed\n * // Result: 2\n * ```\n * \n * ---\n * \n * Example with `options.leading`:\n * ```\n * debounce(1000, doSum(1), { leading: true })\n * // Result: 1\n * // 500ms passed\n * debounce(1000, doSum(2), { leading: true }) // leading doesn't matter anymore in this timer scope\n * // 500ms passed\n * debounce(1000, doSum(3))\n * // 1000ms passed\n * // Result: 3\n * ```\n */\nexport function debounce(ms: number, callback: Fn, { key = callback.toString(), leading }: KontrollDebounceOptions = {}) {\n if (keyStore[key] && !keyStore[key].finishing) { clear(key) }\n else {\n // if no pending call and leading: true, execute function immediately\n if (leading)\n return throttle(ms, callback, { key })\n }\n\n return createTimeout(ms, callback, key)\n}\n\nexport interface KontrollThrottleOptions extends KontrollBaseOptions {\n /**\n * Perform additional execution with last received arguments\n * @default false\n */\n trailing?: boolean\n}\n/**\n * Executes the callback, and bypass any subsequent calls for a period of ms.\n * \n * Calls while the timer haven't finished are dropped.\n * \n * If `options.trailing` and calls while the timer haven't finished are received,\n * \n * an additional execution with last received arguments is performed.\n * \n * ---\n * \n * Example:\n * ```\n * throttle(1000, doSum(1))\n * // Result: 1\n * // 500ms passed\n * throttle(1000, doSum(2))\n * // 9999ms passed\n * // (Nothing)\n * ```\n * \n * ---\n * \n * Example with `options.trailing`:\n * ```\n * throttle(1000, doSum(1))\n * // Result: 1\n * // 500ms passed\n * throttle(1000, doSum(2), { trailing: true })\n * // 500ms passed\n * // Result: 2\n * // A timer is also created, so calls after that are still dropped:\n * throttle(1000, doSum(3))\n * // 9999ms passed\n * // (Nothing)\n * ```\n * \n */\nexport function throttle(ms: number, callback: Fn, { key = callback.toString(), trailing }: KontrollThrottleOptions = {}) {\n if (keyStore[key]) {\n if (trailing)\n keyStore[key].trailing = [throttle, ms, callback, { key }]\n\n return createClearFn(key)\n }\n\n const r = callback()\n\n return createTimeout(ms, () => r, key)\n}\n"],"mappings":";AAcA,MAAM,WAA0B,CAAC;AAIjC,SAAgB,MAAM,SAAmC;CACvD,MAAM,MAAM,OAAO,YAAY,aAAa,QAAQ,SAAS,IAAI;CACjE,IAAI,SAAS,MAAM;EACjB,aAAa,SAAS,IAAI,CAAC,KAAK;EAChC,OAAO,SAAS;CAClB;AACF;;;;;;;;;;;;;;;;AAiBA,SAAgB,YAAY,KAAwD;CAClF,OAAO,SAAS;AAClB;AAGA,SAAS,cAAc,KAA2C;CAChE,aAAa;EAAE,MAAM,GAAG;CAAE;AAC5B;AAEA,eAAe,OAAO,KAA0B;CAC9C,IAAI,SAAS,MAAM;EACjB,SAAS,IAAI,CAAC,YAAY;EAC1B,MAAM,WAAW,SAAS,IAAI,CAAC;EAE/B,MAAM,SAAS,IAAI,CAAC,SAAS;EAE7B,MAAM,GAAG;EAET,IAAI,UACF,SAAS,EAAE,CAAC,GAAG,SAAS,MAAM,CAAC,CAAC;CACpC;AACF;AAEA,SAAS,cAAc,IAAY,UAAc,KAA0B;CACzE,IAAI,SAAS,IAAI,EAAE,WACjB,OAAO,cAAc,GAAG;CAE1B,MAAM,QAAQ,iBACN;EAAE,OAAO,GAAG;CAAE,GACpB,EACF;CAEA,SAAS,OAAO;EACd;EACA;CACF;CAEA,OAAO,cAAc,GAAG;AAC1B;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6CA,SAAgB,UAAU,IAAY,UAAc,EAAE,MAAM,SAAS,SAAS,GAAG,YAAsC,CAAC,GAAG;CACzH,IAAI,SAAS,MAAM;EACjB,IAAI,SACF,SAAS,IAAI,CAAC,WAAW;EAE3B,OAAO,cAAc,GAAG;CAC1B;CAEA,OAAO,cAAc,IAAI,UAAU,GAAG;AACxC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuCA,SAAgB,SAAS,IAAY,UAAc,EAAE,MAAM,SAAS,SAAS,GAAG,YAAqC,CAAC,GAAG;CACvH,IAAI,SAAS,QAAQ,CAAC,SAAS,IAAI,CAAC,WAAa,MAAM,GAAG;MAGxD,IAAI,SACF,OAAO,SAAS,IAAI,UAAU,EAAE,IAAI,CAAC;CAGzC,OAAO,cAAc,IAAI,UAAU,GAAG;AACxC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+CA,SAAgB,SAAS,IAAY,UAAc,EAAE,MAAM,SAAS,SAAS,GAAG,aAAsC,CAAC,GAAG;CACxH,IAAI,SAAS,MAAM;EACjB,IAAI,UACF,SAAS,IAAI,CAAC,WAAW;GAAC;GAAU;GAAI;GAAU,EAAE,IAAI;EAAC;EAE3D,OAAO,cAAc,GAAG;CAC1B;CAEA,MAAM,IAAI,SAAS;CAEnB,OAAO,cAAc,UAAU,GAAG,GAAG;AACvC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kontroll",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.2.0",
|
|
5
5
|
"packageManager": "pnpm@12.4.1",
|
|
6
6
|
"description": "kontroll (\"control\") is a tiny, dead-simple package for function behavior controls like debounce, countdown, throttle (limit).",
|
|
7
7
|
"author": "NamesMT <dangquoctrung123@gmail.com>",
|
|
@@ -25,6 +25,9 @@
|
|
|
25
25
|
"rate"
|
|
26
26
|
],
|
|
27
27
|
"sideEffects": false,
|
|
28
|
+
"imports": {
|
|
29
|
+
"#src/*": "./src/*"
|
|
30
|
+
},
|
|
28
31
|
"exports": {
|
|
29
32
|
".": {
|
|
30
33
|
"types": "./dist/index.d.mts",
|
|
@@ -39,20 +42,17 @@
|
|
|
39
42
|
"dist"
|
|
40
43
|
],
|
|
41
44
|
"engines": {
|
|
42
|
-
"node": ">=
|
|
45
|
+
"node": ">=22.0.0"
|
|
43
46
|
},
|
|
44
47
|
"scripts": {
|
|
45
48
|
"start": "NODE_ENV=dev tsx src/index.ts",
|
|
46
49
|
"watch": "NODE_ENV=dev tsx watch src/index.ts",
|
|
47
|
-
"stub": "unbuild --stub",
|
|
48
50
|
"dev": "pnpm run watch",
|
|
49
|
-
"play": "pnpm run stub && pnpm run --filter playground dev",
|
|
50
|
-
"play:useBuild": "pnpm run build && pnpm run --filter playground dev",
|
|
51
51
|
"lint": "eslint .",
|
|
52
52
|
"test": "vitest",
|
|
53
53
|
"test:types": "tsc --noEmit --skipLibCheck",
|
|
54
54
|
"check": "pnpm lint && pnpm test:types && vitest run --coverage",
|
|
55
|
-
"build": "
|
|
55
|
+
"build": "tsdown",
|
|
56
56
|
"release": "pnpm dlx changelogen@latest --release --push --publish",
|
|
57
57
|
"prepare": "simple-git-hooks",
|
|
58
58
|
"prepublishOnly": "pnpm run build"
|
|
@@ -64,9 +64,9 @@
|
|
|
64
64
|
"eslint": "^9.39.5",
|
|
65
65
|
"lint-staged": "^15.5.2",
|
|
66
66
|
"simple-git-hooks": "^2.14.0",
|
|
67
|
+
"tsdown": "^0.23.0",
|
|
67
68
|
"tsx": "^4.23.13",
|
|
68
69
|
"typescript": "^5.9.3",
|
|
69
|
-
"unbuild": "^3.6.1",
|
|
70
70
|
"vitest": "^3.2.7"
|
|
71
71
|
},
|
|
72
72
|
"simple-git-hooks": {
|
package/dist/index.d.ts
DELETED
|
@@ -1,159 +0,0 @@
|
|
|
1
|
-
type Fn<T = void> = () => T;
|
|
2
|
-
type FnWithArgs<T = void> = (...args: any) => T;
|
|
3
|
-
interface KontrollStore {
|
|
4
|
-
[x: PropertyKey]: KontrollInstance;
|
|
5
|
-
}
|
|
6
|
-
interface KontrollInstance {
|
|
7
|
-
timer: ReturnType<typeof setTimeout>;
|
|
8
|
-
callback: Fn<any | Promise<any>>;
|
|
9
|
-
trailing?: [FnWithArgs, ...any];
|
|
10
|
-
finishing?: boolean;
|
|
11
|
-
}
|
|
12
|
-
declare function clear(callback: Fn): void;
|
|
13
|
-
declare function clear(key: keyof KontrollStore): void;
|
|
14
|
-
/**
|
|
15
|
-
* Returns the {@link KontrollInstance} for the given key, if exists.
|
|
16
|
-
*
|
|
17
|
-
* Could be useful to check if a promise is executing and not settled.
|
|
18
|
-
*
|
|
19
|
-
* ---
|
|
20
|
-
*
|
|
21
|
-
* Example
|
|
22
|
-
* ```
|
|
23
|
-
* debounce(1, async => await sleep(1000), { key: '1sec' })
|
|
24
|
-
* // 500ms passed
|
|
25
|
-
* getInstance('1sec')
|
|
26
|
-
* // Result: `KontrollInstance` ({ timer: Timeout, callback: <fn>, finishing: true })
|
|
27
|
-
* ```
|
|
28
|
-
*/
|
|
29
|
-
declare function getInstance(key: keyof KontrollStore): KontrollInstance | undefined;
|
|
30
|
-
type KontrollClearer = Fn;
|
|
31
|
-
interface KontrollBaseOptions {
|
|
32
|
-
/**
|
|
33
|
-
* Specify a known key if needed
|
|
34
|
-
* @default string // .toString() of the inputted callback
|
|
35
|
-
*/
|
|
36
|
-
key?: keyof KontrollStore;
|
|
37
|
-
}
|
|
38
|
-
interface KontrollCountdownOptions extends KontrollBaseOptions {
|
|
39
|
-
/**
|
|
40
|
-
* Replaces the current timed callback
|
|
41
|
-
* @default false
|
|
42
|
-
*/
|
|
43
|
-
replace?: boolean;
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* Countdown for a period of ms then execute the first/replaced callback, based on `options.replace`.
|
|
47
|
-
*
|
|
48
|
-
* Calls while the timer haven't finished are dropped.
|
|
49
|
-
*
|
|
50
|
-
* ---
|
|
51
|
-
*
|
|
52
|
-
* Example
|
|
53
|
-
* ```
|
|
54
|
-
* countdown(1000, doSum(1), { key: 'eg' })
|
|
55
|
-
* // 500ms passed
|
|
56
|
-
* countdown(1000, doSum(2))
|
|
57
|
-
* // 500ms passed
|
|
58
|
-
* // Result: 1
|
|
59
|
-
* ```
|
|
60
|
-
*
|
|
61
|
-
* ---
|
|
62
|
-
*
|
|
63
|
-
* Example with `options.replace=true`:
|
|
64
|
-
* ```
|
|
65
|
-
* countdown(1000, doSum(1))
|
|
66
|
-
* // 500ms passed
|
|
67
|
-
* countdown(1000, doSum(2), { replace: true })
|
|
68
|
-
* // 500ms passed
|
|
69
|
-
* // Result: 2
|
|
70
|
-
* ```
|
|
71
|
-
*/
|
|
72
|
-
declare function countdown(ms: number, callback: Fn, { key, replace }?: KontrollCountdownOptions): KontrollClearer;
|
|
73
|
-
interface KontrollDebounceOptions extends KontrollBaseOptions {
|
|
74
|
-
/**
|
|
75
|
-
* Avoiding initial wait for first call
|
|
76
|
-
* @default false
|
|
77
|
-
*/
|
|
78
|
-
leading?: boolean;
|
|
79
|
-
}
|
|
80
|
-
/**
|
|
81
|
-
* Creates a timer that will execute the callback upon finish, calls while the timer haven't finished recreates the timer.
|
|
82
|
-
*
|
|
83
|
-
* If `options.leading`, execute callback immediately for initial call.
|
|
84
|
-
*
|
|
85
|
-
* ---
|
|
86
|
-
*
|
|
87
|
-
* Example:
|
|
88
|
-
* ```
|
|
89
|
-
* debounce(1000, doSum(1))
|
|
90
|
-
* // 500ms passed
|
|
91
|
-
* debounce(1000, doSum(2))
|
|
92
|
-
* // 1000ms passed
|
|
93
|
-
* // Result: 2
|
|
94
|
-
* ```
|
|
95
|
-
*
|
|
96
|
-
* ---
|
|
97
|
-
*
|
|
98
|
-
* Example with `options.leading`:
|
|
99
|
-
* ```
|
|
100
|
-
* debounce(1000, doSum(1), { leading: true })
|
|
101
|
-
* // Result: 1
|
|
102
|
-
* // 500ms passed
|
|
103
|
-
* debounce(1000, doSum(2), { leading: true }) // leading doesn't matter anymore in this timer scope
|
|
104
|
-
* // 500ms passed
|
|
105
|
-
* debounce(1000, doSum(3))
|
|
106
|
-
* // 1000ms passed
|
|
107
|
-
* // Result: 3
|
|
108
|
-
* ```
|
|
109
|
-
*/
|
|
110
|
-
declare function debounce(ms: number, callback: Fn, { key, leading }?: KontrollDebounceOptions): KontrollClearer;
|
|
111
|
-
interface KontrollThrottleOptions extends KontrollBaseOptions {
|
|
112
|
-
/**
|
|
113
|
-
* Perform additional execution with last received arguments
|
|
114
|
-
* @default false
|
|
115
|
-
*/
|
|
116
|
-
trailing?: boolean;
|
|
117
|
-
}
|
|
118
|
-
/**
|
|
119
|
-
* Executes the callback, and bypass any subsequent calls for a period of ms.
|
|
120
|
-
*
|
|
121
|
-
* Calls while the timer haven't finished are dropped.
|
|
122
|
-
*
|
|
123
|
-
* If `options.trailing` and calls while the timer haven't finished are received,
|
|
124
|
-
*
|
|
125
|
-
* an additional execution with last received arguments is performed.
|
|
126
|
-
*
|
|
127
|
-
* ---
|
|
128
|
-
*
|
|
129
|
-
* Example:
|
|
130
|
-
* ```
|
|
131
|
-
* throttle(1000, doSum(1))
|
|
132
|
-
* // Result: 1
|
|
133
|
-
* // 500ms passed
|
|
134
|
-
* throttle(1000, doSum(2))
|
|
135
|
-
* // 9999ms passed
|
|
136
|
-
* // (Nothing)
|
|
137
|
-
* ```
|
|
138
|
-
*
|
|
139
|
-
* ---
|
|
140
|
-
*
|
|
141
|
-
* Example with `options.trailing`:
|
|
142
|
-
* ```
|
|
143
|
-
* throttle(1000, doSum(1))
|
|
144
|
-
* // Result: 1
|
|
145
|
-
* // 500ms passed
|
|
146
|
-
* throttle(1000, doSum(2), { trailing: true })
|
|
147
|
-
* // 500ms passed
|
|
148
|
-
* // Result: 2
|
|
149
|
-
* // A timer is also created, so calls after that are still dropped:
|
|
150
|
-
* throttle(1000, doSum(3))
|
|
151
|
-
* // 9999ms passed
|
|
152
|
-
* // (Nothing)
|
|
153
|
-
* ```
|
|
154
|
-
*
|
|
155
|
-
*/
|
|
156
|
-
declare function throttle(ms: number, callback: Fn, { key, trailing }?: KontrollThrottleOptions): KontrollClearer;
|
|
157
|
-
|
|
158
|
-
export { clear, countdown, debounce, getInstance, throttle };
|
|
159
|
-
export type { KontrollBaseOptions, KontrollClearer, KontrollCountdownOptions, KontrollDebounceOptions, KontrollInstance, KontrollStore, KontrollThrottleOptions };
|