@nemigo/helpers 0.13.2 → 1.5.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.
Files changed (111) hide show
  1. package/dist/aggregator.d.ts +33 -0
  2. package/dist/aggregator.js +44 -0
  3. package/dist/array.d.ts +33 -0
  4. package/dist/array.js +24 -0
  5. package/dist/async/context.d.ts +73 -0
  6. package/dist/async/context.js +90 -0
  7. package/dist/async/future.d.ts +54 -0
  8. package/dist/async/future.js +71 -0
  9. package/dist/async/index.d.ts +56 -27
  10. package/dist/async/index.js +63 -58
  11. package/dist/async/loader.d.ts +67 -0
  12. package/dist/async/loader.js +101 -0
  13. package/dist/async/queue.d.ts +51 -0
  14. package/dist/async/queue.js +84 -0
  15. package/dist/cases.d.ts +31 -21
  16. package/dist/cases.js +41 -37
  17. package/dist/clean.d.ts +44 -26
  18. package/dist/clean.js +67 -42
  19. package/dist/color/types.d.ts +31 -0
  20. package/dist/color/types.js +1 -0
  21. package/dist/datetime/delta.d.ts +28 -0
  22. package/dist/datetime/delta.js +65 -0
  23. package/dist/datetime/format.d.ts +53 -0
  24. package/dist/datetime/format.js +119 -0
  25. package/dist/datetime/index.d.ts +6 -0
  26. package/dist/datetime/index.js +22 -0
  27. package/dist/datetime/plural.d.ts +77 -0
  28. package/dist/datetime/plural.js +78 -0
  29. package/dist/emitter.d.ts +29 -17
  30. package/dist/emitter.js +35 -21
  31. package/dist/explorer.d.ts +22 -29
  32. package/dist/explorer.js +18 -16
  33. package/dist/files.d.ts +31 -2
  34. package/dist/files.js +33 -8
  35. package/dist/fish.d.ts +29 -0
  36. package/dist/fish.js +70 -0
  37. package/dist/html/cookie.d.ts +48 -0
  38. package/dist/html/cookie.js +37 -0
  39. package/dist/html/events.d.ts +133 -0
  40. package/dist/html/events.js +139 -0
  41. package/dist/html/index.d.ts +31 -0
  42. package/dist/html/index.js +61 -0
  43. package/dist/index.d.ts +38 -40
  44. package/dist/index.js +43 -56
  45. package/dist/jiff/apply.d.ts +93 -0
  46. package/dist/jiff/apply.js +64 -0
  47. package/dist/jiff/extract.d.ts +7 -0
  48. package/dist/jiff/extract.js +82 -0
  49. package/dist/jiff/types.d.ts +57 -0
  50. package/dist/jiff/types.js +1 -0
  51. package/dist/lens.d.ts +20 -31
  52. package/dist/lens.js +22 -37
  53. package/dist/msgpack.d.ts +11 -26
  54. package/dist/msgpack.js +9 -21
  55. package/dist/mutate.d.ts +70 -0
  56. package/dist/mutate.js +130 -0
  57. package/dist/omitter.d.ts +57 -34
  58. package/dist/omitter.js +38 -30
  59. package/dist/path.d.ts +20 -1
  60. package/dist/path.js +21 -2
  61. package/dist/phymath/format.d.ts +60 -0
  62. package/dist/phymath/format.js +34 -0
  63. package/dist/phymath/index.d.ts +30 -30
  64. package/dist/phymath/index.js +41 -33
  65. package/dist/promoter.d.ts +23 -12
  66. package/dist/promoter.js +24 -17
  67. package/dist/random.d.ts +20 -21
  68. package/dist/random.js +22 -23
  69. package/dist/rubles.d.ts +24 -0
  70. package/dist/rubles.js +24 -0
  71. package/dist/script.d.ts +60 -13
  72. package/dist/script.js +46 -10
  73. package/dist/string.d.ts +46 -92
  74. package/dist/string.js +46 -171
  75. package/dist/types.d.ts +144 -25
  76. package/dist/url/index.d.ts +12 -0
  77. package/dist/url/index.js +17 -0
  78. package/dist/url/params.d.ts +141 -0
  79. package/dist/{url.js → url/params.js} +90 -18
  80. package/dist/url/slug.d.ts +28 -0
  81. package/dist/url/slug.js +102 -0
  82. package/dist/veil.d.ts +14 -0
  83. package/dist/veil.js +26 -0
  84. package/dist/xod.d.ts +237 -16
  85. package/dist/xod.js +192 -18
  86. package/dist/zipper.d.ts +22 -4
  87. package/dist/zipper.js +22 -5
  88. package/package.json +82 -34
  89. package/dist/async/space.d.ts +0 -7
  90. package/dist/async/space.js +0 -31
  91. package/dist/cleanup.d.ts +0 -9
  92. package/dist/cleanup.js +0 -18
  93. package/dist/colors.d.ts +0 -539
  94. package/dist/colors.js +0 -888
  95. package/dist/cookie.d.ts +0 -60
  96. package/dist/cookie.js +0 -48
  97. package/dist/datetime.d.ts +0 -82
  98. package/dist/datetime.js +0 -161
  99. package/dist/format.d.ts +0 -36
  100. package/dist/format.js +0 -26
  101. package/dist/future.d.ts +0 -50
  102. package/dist/future.js +0 -59
  103. package/dist/html.d.ts +0 -145
  104. package/dist/html.js +0 -205
  105. package/dist/humanly.d.ts +0 -9
  106. package/dist/humanly.js +0 -93
  107. package/dist/lru.d.ts +0 -77
  108. package/dist/lru.js +0 -128
  109. package/dist/queue.d.ts +0 -39
  110. package/dist/queue.js +0 -54
  111. package/dist/url.d.ts +0 -61
@@ -0,0 +1,33 @@
1
+ import type { CanBePromise } from "./types.js";
2
+ export type AFunc = () => CanBePromise;
3
+ /**
4
+ * Aggregator для группового выполнения функций
5
+ *
6
+ * Позволяет собирать функции и выполнять их все вместе.
7
+ * Может использоваться для очистки, уведомлений, batch-операций и т.д.
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * const runner = new Aggregator();
12
+ * runner.add(() => console.log("First run"));
13
+ * runner.run();
14
+ * runner.add(() => console.log("Second run"));
15
+ * runner.run();
16
+ * ```
17
+ */
18
+ export declare class Aggregator {
19
+ __calls: AFunc[];
20
+ /**
21
+ * @param calls - Начальные функции для выполнения
22
+ */
23
+ constructor(...calls: AFunc[]);
24
+ push(...calls: AFunc[]): this;
25
+ /**
26
+ * @param [promise=false] - Есть асинхронные функции и нужно дождаться их выполнения
27
+ */
28
+ run(promise?: false): void;
29
+ /**
30
+ * @param promise - Есть асинхронные функции и нужно дождаться их выполнения
31
+ */
32
+ run(promise: true): Promise<void>;
33
+ }
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Aggregator для группового выполнения функций
3
+ *
4
+ * Позволяет собирать функции и выполнять их все вместе.
5
+ * Может использоваться для очистки, уведомлений, batch-операций и т.д.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * const runner = new Aggregator();
10
+ * runner.add(() => console.log("First run"));
11
+ * runner.run();
12
+ * runner.add(() => console.log("Second run"));
13
+ * runner.run();
14
+ * ```
15
+ */
16
+ export class Aggregator {
17
+ __calls = [];
18
+ /**
19
+ * @param calls - Начальные функции для выполнения
20
+ */
21
+ constructor(...calls) {
22
+ this.__calls = calls;
23
+ }
24
+ push(...calls) {
25
+ this.__calls.push(...calls);
26
+ return this;
27
+ }
28
+ /**
29
+ * @param [promise=false] - Есть асинхронные функции и нужно дождаться их выполнения
30
+ */
31
+ run(promise = false) {
32
+ if (promise) {
33
+ return (async () => {
34
+ await Promise.allSettled(this.__calls.map(async (f) => f()));
35
+ this.__calls.length = 0;
36
+ })();
37
+ }
38
+ else {
39
+ for (const call of this.__calls)
40
+ void call();
41
+ this.__calls.length = 0;
42
+ }
43
+ }
44
+ }
@@ -0,0 +1,33 @@
1
+ import type { CanBeArray, CanBeReadonlyArray } from "./types.js";
2
+ /**
3
+ * Приведение значения к массиву
4
+ */
5
+ export declare const arrayble: <T>(v: CanBeArray<T> | CanBeReadonlyArray<T>) => T[];
6
+ /**
7
+ * Тип разделения для функции {@link partition}
8
+ */
9
+ export interface Partition<T> {
10
+ /**
11
+ * Элементы, удовлетворяющие условию
12
+ */
13
+ result: T[];
14
+ /**
15
+ * Исключённые элементы
16
+ */
17
+ excluded: T[];
18
+ }
19
+ /**
20
+ * Разделяет массив на два по условию
21
+ */
22
+ export declare const partition: <T>(arr: CanBeReadonlyArray<T>, filter: (item: T) => boolean, initial?: Partition<T>) => Partition<T>;
23
+ /**
24
+ * Удаляет `null` и `undefined` и оставляет только уникальные строки
25
+ */
26
+ export declare const setify: (arr: CanBeReadonlyArray<string | undefined | null>) => string[];
27
+ /**
28
+ * Удаляет дубликаты объектов из массива на основе указанного ключа
29
+ *
30
+ * @param arr - Исходный массив объектов
31
+ * @param [key="id"] - Ключ, по которому будут удаляться дубликаты
32
+ */
33
+ export declare const unify: <T, K extends keyof T>(arr: CanBeReadonlyArray<T>, key?: K) => T[];
package/dist/array.js ADDED
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Приведение значения к массиву
3
+ */
4
+ export const arrayble = (v) => (Array.isArray(v) ? v : [v]);
5
+ /**
6
+ * Разделяет массив на два по условию
7
+ */
8
+ export const partition = (arr, filter, initial = { result: [], excluded: [] }) => arr.reduce((acc, item) => (acc[filter(item) ? "result" : "excluded"].push(item), acc), initial);
9
+ //...
10
+ /**
11
+ * Удаляет `null` и `undefined` и оставляет только уникальные строки
12
+ */
13
+ export const setify = (arr) => [
14
+ ...new Set(arr.filter((item) => typeof item === "string")),
15
+ ];
16
+ /**
17
+ * Удаляет дубликаты объектов из массива на основе указанного ключа
18
+ *
19
+ * @param arr - Исходный массив объектов
20
+ * @param [key="id"] - Ключ, по которому будут удаляться дубликаты
21
+ */
22
+ export const unify = (arr, key = "id") => [
23
+ ...new Map(arr.map((item) => [item[key], item])).values(),
24
+ ];
@@ -0,0 +1,73 @@
1
+ import type { CanBePromise } from "../types.js";
2
+ import { AsyncLocalStorage } from "async_hooks";
3
+ /**
4
+ * Создание асинхронного контекста с транзакциями без явной передачи на основе {@link AsyncLocalStorage}
5
+ *
6
+ * @template TX - Тип операций в транзакции
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * class Database extends AsyncContext<Query> {
11
+ * protected async submit(tx: Query[]): Promise<void> {
12
+ * await database.executeBatch(tx);
13
+ * }
14
+ * }
15
+ *
16
+ * const database = new Database();
17
+ * const result = await database.space(async (tx) => {
18
+ * tx.push(new Query("INSERT ..."));
19
+ * await nestedFunction();
20
+ * return someOperation();
21
+ * });
22
+ *
23
+ * async function nestedFunction() {
24
+ * const tx = database.getTX();
25
+ * tx.push(new Query("UPDATE ..."));
26
+ * }
27
+ * ```
28
+ */
29
+ export declare abstract class AsyncContext<TX> {
30
+ __async_storage: AsyncLocalStorage<TX[]>;
31
+ /**
32
+ * Получает текущий массив операций транзакции из асинхронного контекста
33
+ *
34
+ * Работает в любом месте цепочки асинхронных вызовов, запущенных внутри {@link space}
35
+ *
36
+ * @throws {Error} Если вызвано вне контекста space()
37
+ */
38
+ getTX(): TX[];
39
+ /**
40
+ * Создаёт асинхронное пространство транзакции
41
+ *
42
+ * Всё внутри `func` получает доступ к одной транзакции через {@link getTX}
43
+ *
44
+ * @param func - Функция для выполнения в транзакции
45
+ * @param [autoAfterCommit=true] - Автоматический вызов {@link commit} после завершения
46
+ */
47
+ space<T>(func: (tx: TX[]) => CanBePromise<T>, autoAfterCommit?: boolean): Promise<T>;
48
+ /**
49
+ * Выполняет накопленные операции и очищает транзакцию
50
+ *
51
+ * @remarks Можно вызвать во вложенных функциях, но это будет антипаттерн
52
+ *
53
+ * @throws {Error} Если вызвано вне контекста space()
54
+ *
55
+ * @example
56
+ * ```typescript
57
+ * await database.space(async (tx) => {
58
+ * tx.push(operation1);
59
+ *
60
+ * await database.commit(); // Выполняем operation1
61
+ *
62
+ * tx.push(operation2); // operation2 будет уже в новой транзакции
63
+ * });
64
+ * ```
65
+ */
66
+ commit(): Promise<void>;
67
+ /**
68
+ * Выполняет накопленные операции (например, запись в БД, отправка в очередь и т.д.)
69
+ *
70
+ * @remarks `transaction.length = 0` не требуется — это делают вызывающие методы после
71
+ */
72
+ abstract __submit(transaction: TX[]): Promise<void>;
73
+ }
@@ -0,0 +1,90 @@
1
+ import { AsyncLocalStorage } from "async_hooks";
2
+ /**
3
+ * Создание асинхронного контекста с транзакциями без явной передачи на основе {@link AsyncLocalStorage}
4
+ *
5
+ * @template TX - Тип операций в транзакции
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * class Database extends AsyncContext<Query> {
10
+ * protected async submit(tx: Query[]): Promise<void> {
11
+ * await database.executeBatch(tx);
12
+ * }
13
+ * }
14
+ *
15
+ * const database = new Database();
16
+ * const result = await database.space(async (tx) => {
17
+ * tx.push(new Query("INSERT ..."));
18
+ * await nestedFunction();
19
+ * return someOperation();
20
+ * });
21
+ *
22
+ * async function nestedFunction() {
23
+ * const tx = database.getTX();
24
+ * tx.push(new Query("UPDATE ..."));
25
+ * }
26
+ * ```
27
+ */
28
+ export class AsyncContext {
29
+ __async_storage = new AsyncLocalStorage();
30
+ /**
31
+ * Получает текущий массив операций транзакции из асинхронного контекста
32
+ *
33
+ * Работает в любом месте цепочки асинхронных вызовов, запущенных внутри {@link space}
34
+ *
35
+ * @throws {Error} Если вызвано вне контекста space()
36
+ */
37
+ getTX() {
38
+ const ctx = this.__async_storage.getStore();
39
+ if (ctx)
40
+ return ctx;
41
+ throw new Error("getTX() called outside of space() context");
42
+ }
43
+ /**
44
+ * Создаёт асинхронное пространство транзакции
45
+ *
46
+ * Всё внутри `func` получает доступ к одной транзакции через {@link getTX}
47
+ *
48
+ * @param func - Функция для выполнения в транзакции
49
+ * @param [autoAfterCommit=true] - Автоматический вызов {@link commit} после завершения
50
+ */
51
+ async space(func, autoAfterCommit = true) {
52
+ const ctx = this.__async_storage.getStore();
53
+ if (ctx)
54
+ return func(ctx);
55
+ const transaction = [];
56
+ const result = await this.__async_storage.run(transaction, () => func(transaction));
57
+ if (autoAfterCommit && transaction.length > 0) {
58
+ await this.__submit(transaction);
59
+ transaction.length = 0;
60
+ }
61
+ return result;
62
+ }
63
+ /**
64
+ * Выполняет накопленные операции и очищает транзакцию
65
+ *
66
+ * @remarks Можно вызвать во вложенных функциях, но это будет антипаттерн
67
+ *
68
+ * @throws {Error} Если вызвано вне контекста space()
69
+ *
70
+ * @example
71
+ * ```typescript
72
+ * await database.space(async (tx) => {
73
+ * tx.push(operation1);
74
+ *
75
+ * await database.commit(); // Выполняем operation1
76
+ *
77
+ * tx.push(operation2); // operation2 будет уже в новой транзакции
78
+ * });
79
+ * ```
80
+ */
81
+ async commit() {
82
+ const transaction = this.__async_storage.getStore();
83
+ if (!transaction)
84
+ throw new Error("commit() called outside of space() context");
85
+ if (transaction.length > 0) {
86
+ await this.__submit(transaction);
87
+ transaction.length = 0;
88
+ }
89
+ }
90
+ }
@@ -0,0 +1,54 @@
1
+ import type { CanBePromise, IntervalType, RID, TimeoutType } from "../types.js";
2
+ /**
3
+ * Типы фьючерса из {@link Future}:
4
+ * - `"timer"` — Однократный
5
+ * - `"interval"` — Повторяющийся
6
+ */
7
+ export type FutureType = "timer" | "interval";
8
+ /**
9
+ * Опции запуска фьючерса из {@link Future}
10
+ */
11
+ export interface FutureRunOptions {
12
+ type?: FutureType;
13
+ key?: RID;
14
+ delay?: number;
15
+ }
16
+ type InternalFuture = {
17
+ type: "timer";
18
+ id: TimeoutType;
19
+ } | {
20
+ type: "interval";
21
+ id: IntervalType;
22
+ };
23
+ /**
24
+ * Управление таймерами и интервалами
25
+ */
26
+ export declare class Future {
27
+ delay: number;
28
+ /**
29
+ * @param [delay=5min] - Задержка по умолчанию
30
+ */
31
+ constructor(delay?: number);
32
+ __entries: Map<RID, InternalFuture>;
33
+ __delete(key: RID, entry: InternalFuture): void;
34
+ /**
35
+ * @param key - Ключ фьючерса. Если не указан — **очищаются все**
36
+ */
37
+ clear(key?: RID): void;
38
+ has(key: RID): FutureType | undefined;
39
+ /**
40
+ * Очищает существующий фьючерс по ключу (если он был) и запускает новый
41
+ *
42
+ * @param func - Функция для выполнения
43
+ * @param [options] - Опции запуска
44
+ * @param [options.type="timer"] - Тип фьючерса
45
+ * @param [options.key=Symbol()] - Ключ фьючерса
46
+ * @param [options.delay=this.delay] - Задержка в миллисекундах
47
+ *
48
+ * @return Функция для очистки
49
+ *
50
+ * @remarks Ошибки полностью игнорируются
51
+ */
52
+ run(func: () => CanBePromise, { type, key: __key, delay }?: FutureRunOptions): () => void;
53
+ }
54
+ export {};
@@ -0,0 +1,71 @@
1
+ import { MS_IN_MINUTE } from "../datetime/delta.js";
2
+ /**
3
+ * Управление таймерами и интервалами
4
+ */
5
+ export class Future {
6
+ delay;
7
+ /**
8
+ * @param [delay=5min] - Задержка по умолчанию
9
+ */
10
+ constructor(delay = 5 * MS_IN_MINUTE) {
11
+ this.delay = delay;
12
+ }
13
+ __entries = new Map();
14
+ __delete(key, entry) {
15
+ entry.type === "timer" ? clearTimeout(entry.id) : clearInterval(entry.id);
16
+ this.__entries.delete(key);
17
+ }
18
+ /**
19
+ * @param key - Ключ фьючерса. Если не указан — **очищаются все**
20
+ */
21
+ clear(key) {
22
+ if (key === undefined) {
23
+ for (const [k, entry] of this.__entries)
24
+ this.__delete(k, entry);
25
+ }
26
+ else {
27
+ const entry = this.__entries.get(key);
28
+ if (entry)
29
+ this.__delete(key, entry);
30
+ }
31
+ }
32
+ has(key) {
33
+ return this.__entries.get(key)?.type;
34
+ }
35
+ /**
36
+ * Очищает существующий фьючерс по ключу (если он был) и запускает новый
37
+ *
38
+ * @param func - Функция для выполнения
39
+ * @param [options] - Опции запуска
40
+ * @param [options.type="timer"] - Тип фьючерса
41
+ * @param [options.key=Symbol()] - Ключ фьючерса
42
+ * @param [options.delay=this.delay] - Задержка в миллисекундах
43
+ *
44
+ * @return Функция для очистки
45
+ *
46
+ * @remarks Ошибки полностью игнорируются
47
+ */
48
+ run(func, { type = "timer", key: __key, delay = this.delay } = {}) {
49
+ if (__key !== undefined)
50
+ this.clear(__key);
51
+ const key = __key ?? Symbol();
52
+ let id;
53
+ if (type === "timer") {
54
+ const futures = async () => {
55
+ try {
56
+ await func();
57
+ }
58
+ finally {
59
+ this.__entries.delete(key);
60
+ }
61
+ };
62
+ id = setTimeout(() => void futures(), delay);
63
+ }
64
+ else {
65
+ id = setInterval(() => void func(), delay);
66
+ }
67
+ const entry = { type, id };
68
+ this.__entries.set(key, entry);
69
+ return () => this.__delete(key, entry);
70
+ }
71
+ }
@@ -1,40 +1,69 @@
1
- import type { Timestamp } from "../types.js";
1
+ import type { AnyFunc, Args, CanBePromise, Return } from "../types.js";
2
2
  /**
3
- * Создаёт задержку на указанное количество миллисекунд
3
+ * Промис из {@link createManualPromise}
4
4
  */
5
- export declare const delay: (ms: Timestamp, success?: boolean) => Promise<void>;
5
+ export interface ManualPromise<T = void, E = Error> {
6
+ promise: Promise<T>;
7
+ resolve: (result: T) => void;
8
+ reject: (err: E) => void;
9
+ }
10
+ export declare const createManualPromise: <T = void, E = Error>() => ManualPromise<T, E>;
11
+ /**
12
+ * Создаёт промис, завершающийся через заданное время
13
+ *
14
+ * @param ms - Время задержки в миллисекундах
15
+ * @param [success=true] - Завершать успехом или отклонять
16
+ *
17
+ * @remarks При `success = false` промис отклоняется с ошибкой `"delay rejected"`
18
+ */
19
+ export declare const delay: (ms: number, success?: boolean) => Promise<void>;
6
20
  /**
7
21
  * Создаёт debounce-функцию, которая откладывает выполнение до тех пор, пока не пройдёт указанное время без новых вызовов
8
22
  *
9
- * @param call - Функция для debounce
10
- * @param delay - Задержка в миллисекундах
23
+ * @remarks Ошибки полностью игнорируются
24
+ * @remarks Если нужен результат, используйте {@link throttle}
11
25
  *
12
- * @returns Функция с debounce
26
+ * @example
27
+ * ```typescript
28
+ * const debouncedMethod = debounce(this.method.bind(this), 200);
29
+ * const debouncedFunc = debounce((value: string) => func(value), 300);
30
+ * ```
13
31
  */
14
- export declare const debounce: <T extends (...args: any[]) => any>(call: T, delay: Timestamp) => ((...args: Parameters<T>) => void);
32
+ export declare const debounce: <F extends AnyFunc>(func: F, ms: number) => ((...args: Args<F>) => void);
15
33
  /**
16
- * Создаёт функцию-замыкание, которое гарантирует (старается), что переданная функция `call`
17
- * будет вызвана не чаще одного раза в заданный интервал времени.
18
- *
19
- * mode = `"delay"`
20
- * - первый вызов откладывается на `ms`
21
- * - повторные вызовы до старта игнорируются, аргументы обновляются
22
- * - все ждут одного промисса
23
- *
24
- * mode = `"urgent"`:
25
- * - первый вызов исполняется сразу
26
- * - повторные вызовы возвращают тот же промисс в течение `ms` (даже после завершения)
27
- * - после `ms` можно снова вызвать
34
+ * Режимы троттлинга для {@link throttle}:
35
+ * - `"delay"`:
36
+ * * Первый вызов откладывается на `ms`
37
+ * * Повторные вызовы до старта игнорируются
38
+ * * Аргументы обновляются
39
+ * - `"urgent"`:
40
+ * * Первый вызов исполняется сразу
41
+ * * Повторные вызовы возвращают тот же промис в течение `ms`
42
+ * * Аргументы обновляются, но не влияют, если функция уже выполняется
28
43
  */
29
- export declare const throttle: <F extends (...args: any[]) => any>(call: F, mode: "urgent" | "delay", ms: number) => ((...args: Parameters<F>) => Promise<Awaited<ReturnType<F>>>);
44
+ export type ThrottleMode = "urgent" | "delay";
30
45
  /**
31
- * Создаёт функцию-замыкание, которая гарантирует однократное выполнение асинхронной операции
46
+ * Создаёт throttle-функцию, которая вызывает переданную функцию не чаще одного раза в заданный интервал времени
32
47
  *
33
- * При первом вызове запускает переданный `call` и сохраняет его результат.
34
- * Все последующие вызовы возвращают сохранённый результат без повторного выполнения операции.
35
- * Если вызов происходит во время выполнения, возвращает тот же промисс, вместо создания нового
48
+ * @param func - Функция для троттлинга
49
+ * @param [mode="urgent"] - Режим троттлинга
50
+ * @param [ms=250] - Интервал времени в миллисекундах
36
51
  *
37
- * @param call - Асинхронная функция, результат которой нужно кешировать
38
- * @returns Функция, возвращающая закешированный результат после первого успешного выполнения
52
+ * @throws {unknown} Ошибки функции прокидываются в промис
53
+ *
54
+ * @example
55
+ * ```typescript
56
+ * const throttledScroll = throttle((position) => saveScrollPosition(position), "delay", 100);
57
+ * window.addEventListener("scroll", () => void throttledScroll(window.scrollY)); // выполнится через 100 ms с самым последним scrollY
58
+ *
59
+ * const throttledFetch = throttle((id: string) => fetch(`/api/data/${id}`).then(r => r.json()), "urgent", 500);
60
+ * const result1 = await throttledFetch("123"); // Выполняется сразу с "123"
61
+ * const result2 = await throttledFetch("456"); // Возвращает тот же промис с "123"
62
+ * ```
63
+ */
64
+ export declare const throttle: <F extends AnyFunc>(func: F, mode?: "urgent" | "delay", ms?: number) => ((...args: Args<F>) => Promise<Awaited<Return<F>>>);
65
+ export type BoundaryFallback<Fallback> = Fallback | ((err: unknown) => CanBePromise<Fallback>);
66
+ /**
67
+ * Приведение коллбэка к промису с отловом ошибок и fallback-значением
39
68
  */
40
- export declare const createPromiseTrap: <T>(call: () => Promise<T>) => () => Promise<T>;
69
+ export declare const boundary: <Result = undefined, Fallback = Result>(func: () => CanBePromise<Result>, fallback?: BoundaryFallback<Fallback>) => Promise<Result | Fallback>;