kontroll 1.1.2 → 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 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
- [x: PropertyKey]: KontrollInstance;
4
+ export interface KontrollStore {
5
+ [x: PropertyKey]: KontrollInstance;
5
6
  }
6
- interface KontrollInstance {
7
- timer: ReturnType<typeof setTimeout>;
8
- callback: Fn<any | Promise<any>>;
9
- trailing?: [FnWithArgs, ...any];
10
- finishing?: boolean;
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
- * Specify a known key if needed
34
- * @default string // .toString() of the inputted callback
35
- */
36
- key?: keyof KontrollStore;
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
- * Replaces the current timed callback
41
- * @default false
42
- */
43
- replace?: boolean;
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
- * Avoiding initial wait for first call
76
- * @default false
77
- */
78
- leading?: boolean;
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
- * Perform additional execution with last received arguments
114
- * @default false
115
- */
116
- trailing?: boolean;
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
- export { clear, countdown, debounce, getInstance, throttle };
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
- const t={};function c(n){const e=typeof n=="function"?n.toString():n;t[e]&&(clearTimeout(t[e].timer),delete t[e])}function a(n){return t[n]}function u(n){return()=>{c(n)}}async function s(n){if(t[n]){t[n].finishing=!0;const e=t[n].trailing;await t[n].callback(),c(n),e&&e[0](...e.slice(1))}}function o(n,e,i){if(t[i]?.finishing)return u(i);const r=setTimeout(()=>{s(i)},n);return t[i]={timer:r,callback:e},u(i)}function g(n,e,{key:i=e.toString(),replace:r}={}){return t[i]?(r&&(t[i].callback=e),u(i)):o(n,e,i)}function k(n,e,{key:i=e.toString(),leading:r}={}){if(t[i]&&!t[i].finishing)c(i);else if(r)return f(n,e,{key:i});return o(n,e,i)}function f(n,e,{key:i=e.toString(),trailing:r}={}){if(t[i])return r&&(t[i].trailing=[f,n,e,{key:i}]),u(i);const l=e();return o(n,()=>l,i)}export{c as clear,g as countdown,k as debounce,a as getInstance,f as throttle};
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,8 @@
1
1
  {
2
2
  "name": "kontroll",
3
3
  "type": "module",
4
- "version": "1.1.2",
4
+ "version": "1.2.0",
5
+ "packageManager": "pnpm@12.4.1",
5
6
  "description": "kontroll (\"control\") is a tiny, dead-simple package for function behavior controls like debounce, countdown, throttle (limit).",
6
7
  "author": "NamesMT <dangquoctrung123@gmail.com>",
7
8
  "license": "MIT",
@@ -24,6 +25,9 @@
24
25
  "rate"
25
26
  ],
26
27
  "sideEffects": false,
28
+ "imports": {
29
+ "#src/*": "./src/*"
30
+ },
27
31
  "exports": {
28
32
  ".": {
29
33
  "types": "./dist/index.d.mts",
@@ -38,38 +42,37 @@
38
42
  "dist"
39
43
  ],
40
44
  "engines": {
41
- "node": ">=18.0.0"
42
- },
43
- "devDependencies": {
44
- "@antfu/eslint-config": "^4.12.0",
45
- "@types/node": "^22.14.0",
46
- "@vitest/coverage-v8": "^3.1.1",
47
- "eslint": "^9.24.0",
48
- "lint-staged": "^15.5.0",
49
- "simple-git-hooks": "^2.12.1",
50
- "tsx": "^4.19.3",
51
- "typescript": "^5.8.3",
52
- "unbuild": "^3.5.0",
53
- "vitest": "^3.1.1"
54
- },
55
- "simple-git-hooks": {
56
- "pre-commit": "pnpm lint-staged"
57
- },
58
- "lint-staged": {
59
- "*": "eslint"
45
+ "node": ">=22.0.0"
60
46
  },
61
47
  "scripts": {
62
48
  "start": "NODE_ENV=dev tsx src/index.ts",
63
49
  "watch": "NODE_ENV=dev tsx watch src/index.ts",
64
- "stub": "unbuild --stub",
65
50
  "dev": "pnpm run watch",
66
- "play": "pnpm run stub && pnpm run --filter playground dev",
67
- "play:useBuild": "pnpm run build && pnpm run --filter playground dev",
68
51
  "lint": "eslint .",
69
52
  "test": "vitest",
70
53
  "test:types": "tsc --noEmit --skipLibCheck",
71
54
  "check": "pnpm lint && pnpm test:types && vitest run --coverage",
72
- "build": "unbuild",
73
- "release": "pnpm dlx changelogen@latest --release --push --publish"
55
+ "build": "tsdown",
56
+ "release": "pnpm dlx changelogen@latest --release --push --publish",
57
+ "prepare": "simple-git-hooks",
58
+ "prepublishOnly": "pnpm run build"
59
+ },
60
+ "devDependencies": {
61
+ "@antfu/eslint-config": "^4.19.0",
62
+ "@types/node": "^22.20.2",
63
+ "@vitest/coverage-v8": "^3.2.7",
64
+ "eslint": "^9.39.5",
65
+ "lint-staged": "^15.5.2",
66
+ "simple-git-hooks": "^2.14.0",
67
+ "tsdown": "^0.23.0",
68
+ "tsx": "^4.23.13",
69
+ "typescript": "^5.9.3",
70
+ "vitest": "^3.2.7"
71
+ },
72
+ "simple-git-hooks": {
73
+ "pre-commit": "pnpm lint-staged"
74
+ },
75
+ "lint-staged": {
76
+ "*": "eslint"
74
77
  }
75
- }
78
+ }
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 };