@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
@@ -1,93 +1,98 @@
1
+ export const createManualPromise = () => {
2
+ let resolve;
3
+ let reject;
4
+ const promise = new Promise((res, rej) => {
5
+ resolve = res;
6
+ reject = rej;
7
+ });
8
+ return { resolve, promise, reject };
9
+ };
10
+ //...
1
11
  /**
2
- * Создаёт задержку на указанное количество миллисекунд
12
+ * Создаёт промис, завершающийся через заданное время
13
+ *
14
+ * @param ms - Время задержки в миллисекундах
15
+ * @param [success=true] - Завершать успехом или отклонять
16
+ *
17
+ * @remarks При `success = false` промис отклоняется с ошибкой `"delay rejected"`
3
18
  */
4
- export const delay = (ms, success = true) => new Promise((resolve, reject) => setTimeout(success ? resolve : reject, ms));
19
+ export const delay = (ms, success = true) => new Promise((resolve, reject) => setTimeout(() => (success ? resolve() : reject(new Error("delay rejected"))), ms));
5
20
  /**
6
21
  * Создаёт debounce-функцию, которая откладывает выполнение до тех пор, пока не пройдёт указанное время без новых вызовов
7
22
  *
8
- * @param call - Функция для debounce
9
- * @param delay - Задержка в миллисекундах
23
+ * @remarks Ошибки полностью игнорируются
24
+ * @remarks Если нужен результат, используйте {@link throttle}
10
25
  *
11
- * @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
+ * ```
12
31
  */
13
- export const debounce = (call, delay) => {
32
+ export const debounce = (func, ms) => {
14
33
  let timeout;
15
34
  return (...args) => {
16
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
17
35
  if (timeout)
18
36
  clearTimeout(timeout);
19
- timeout = setTimeout(() => call(...args), delay);
37
+ timeout = setTimeout(() => void func(...args), ms);
20
38
  };
21
39
  };
22
40
  /**
23
- * Создаёт функцию-замыкание, которое гарантирует (старается), что переданная функция `call`
24
- * будет вызвана не чаще одного раза в заданный интервал времени.
41
+ * Создаёт throttle-функцию, которая вызывает переданную функцию не чаще одного раза в заданный интервал времени
42
+ *
43
+ * @param func - Функция для троттлинга
44
+ * @param [mode="urgent"] - Режим троттлинга
45
+ * @param [ms=250] - Интервал времени в миллисекундах
25
46
  *
26
- * mode = `"delay"`
27
- * - первый вызов откладывается на `ms`
28
- * - повторные вызовы до старта игнорируются, аргументы обновляются
29
- * - все ждут одного промисса
47
+ * @throws {unknown} Ошибки функции прокидываются в промис
30
48
  *
31
- * mode = `"urgent"`:
32
- * - первый вызов исполняется сразу
33
- * - повторные вызовы возвращают тот же промисс в течение `ms` (даже после завершения)
34
- * - после `ms` можно снова вызвать
49
+ * @example
50
+ * ```typescript
51
+ * const throttledScroll = throttle((position) => saveScrollPosition(position), "delay", 100);
52
+ * window.addEventListener("scroll", () => void throttledScroll(window.scrollY)); // выполнится через 100 ms с самым последним scrollY
53
+ *
54
+ * const throttledFetch = throttle((id: string) => fetch(`/api/data/${id}`).then(r => r.json()), "urgent", 500);
55
+ * const result1 = await throttledFetch("123"); // Выполняется сразу с "123"
56
+ * const result2 = await throttledFetch("456"); // Возвращает тот же промис с "123"
57
+ * ```
35
58
  */
36
- export const throttle = (call, mode, ms) => {
37
- let _promise = null;
59
+ export const throttle = (func, mode = "urgent", ms = 250) => {
60
+ let _promise;
38
61
  let _args = [];
62
+ const call = async () => await func(..._args);
63
+ const reset = () => (_promise = null);
39
64
  return (...args) => {
40
65
  _args = args;
41
66
  if (_promise)
42
67
  return _promise;
43
- let resolver;
44
- let rejecter;
45
- _promise = new Promise((resolve, reject) => {
46
- resolver = resolve;
47
- rejecter = reject;
48
- });
49
- const reset = () => (_promise = null);
68
+ const { resolve, reject, promise } = createManualPromise();
69
+ _promise = promise;
50
70
  if (mode === "delay") {
51
71
  setTimeout(() => {
52
- call(..._args)
53
- .then(resolver)
54
- .catch(rejecter)
55
- .finally(reset);
72
+ call().then(resolve).catch(reject).finally(reset);
56
73
  }, ms);
57
74
  }
58
75
  else {
59
- call(..._args)
60
- .then(resolver)
61
- .catch(rejecter)
62
- .finally(delay(ms).then(reset));
76
+ call()
77
+ .then(resolve)
78
+ .catch(reject)
79
+ .finally(() => void delay(ms).then(reset));
63
80
  }
64
81
  return _promise;
65
82
  };
66
83
  };
67
- //...
68
84
  /**
69
- * Создаёт функцию-замыкание, которая гарантирует однократное выполнение асинхронной операции
70
- *
71
- * При первом вызове запускает переданный `call` и сохраняет его результат.
72
- * Все последующие вызовы возвращают сохранённый результат без повторного выполнения операции.
73
- * Если вызов происходит во время выполнения, возвращает тот же промисс, вместо создания нового
74
- *
75
- * @param call - Асинхронная функция, результат которой нужно кешировать
76
- * @returns Функция, возвращающая закешированный результат после первого успешного выполнения
85
+ * Приведение коллбэка к промису с отловом ошибок и fallback-значением
77
86
  */
78
- export const createPromiseTrap = (call) => {
79
- const mark = Symbol();
80
- let value = mark;
81
- let promise = null;
82
- return () => {
83
- if (value !== mark)
84
- return value;
85
- if (!promise) {
86
- promise = call().then((result) => {
87
- value = result;
88
- return result;
89
- });
87
+ export const boundary = async (func, fallback) => {
88
+ try {
89
+ return await func();
90
+ }
91
+ catch (e) {
92
+ if (typeof fallback === "function") {
93
+ // @ts-expect-error <тут не типизировать>
94
+ return fallback(e);
90
95
  }
91
- return promise;
92
- };
96
+ return fallback;
97
+ }
93
98
  };
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Тип хука, возвращаемый методом {@link Loader.hook}
3
+ */
4
+ export type LoaderHook = ReturnType<Loader["hook"]>;
5
+ /**
6
+ * Менеджер состояния выполнения для асинхронных операций
7
+ *
8
+ * Отслеживает активность через очередь промисов: состояние `true`, пока есть незавершённые промисы.
9
+ * Использует версионирование, чтобы избежать гонок при быстрых последовательных вызовах
10
+ */
11
+ export declare class Loader {
12
+ __heap: Promise<unknown>[];
13
+ __version: number;
14
+ __onchange: (v: boolean) => void;
15
+ constructor(onchange: (v: boolean) => void);
16
+ reset(): void;
17
+ __reset(version: number): void;
18
+ __check(version: number): void;
19
+ __awaiter(version: number): void;
20
+ /**
21
+ * Добавляет промис в очередь отслеживания
22
+ *
23
+ * @example
24
+ * ```typescript
25
+ * async function fetchData() {
26
+ * const promise = fetch("/api/data");
27
+ * loader.push(promise);
28
+ * const data = await promise;
29
+ * return data;
30
+ * }
31
+ * ```
32
+ */
33
+ push(promise: Promise<any>): void;
34
+ /**
35
+ * Создаёт хук: возвращает функцию, которая завершает отслеживание при вызове
36
+ *
37
+ * Внутри создаётся промис, добавляемый в очередь. Вызов возвращённой функции разрешает его
38
+ *
39
+ * @example
40
+ * ```typescript
41
+ * const complete = loader.hook();
42
+ * try {
43
+ * await someAsyncOperation();
44
+ * } finally {
45
+ * complete();
46
+ * }
47
+ * ```
48
+ */
49
+ hook(): () => void;
50
+ /**
51
+ * Выполняет функцию и автоматически отслеживает её промис
52
+ *
53
+ * @param func — Асинхронная функция для выполнения
54
+ * @param [external] — Опциональный коллбэк для синхронного уведомления о начале/завершении
55
+ *
56
+ * @throws {unknown} Ошибки промиса функции
57
+ *
58
+ * @example
59
+ * ```typescript
60
+ * async function fetchData() {
61
+ * const data = await loader.run(() => fetch("/api/data"));
62
+ * return data;
63
+ * }
64
+ * ```
65
+ */
66
+ run<T = any>(func: () => Promise<T>, external?: (v: boolean) => void): Promise<T>;
67
+ }
@@ -0,0 +1,101 @@
1
+ import { createManualPromise } from "./index.js";
2
+ /**
3
+ * Менеджер состояния выполнения для асинхронных операций
4
+ *
5
+ * Отслеживает активность через очередь промисов: состояние `true`, пока есть незавершённые промисы.
6
+ * Использует версионирование, чтобы избежать гонок при быстрых последовательных вызовах
7
+ */
8
+ export class Loader {
9
+ __heap = [];
10
+ __version = 0;
11
+ __onchange;
12
+ constructor(onchange) {
13
+ this.__onchange = onchange;
14
+ }
15
+ reset() {
16
+ this.__onchange(false);
17
+ this.__version = 0;
18
+ this.__heap = [];
19
+ }
20
+ //...
21
+ __reset(version) {
22
+ if (this.__version !== version)
23
+ return;
24
+ this.reset();
25
+ }
26
+ __check(version) {
27
+ if (this.__heap.length === 0)
28
+ return this.reset();
29
+ void Promise.allSettled(this.__heap).then(() => this.__reset(version));
30
+ }
31
+ __awaiter(version) {
32
+ this.__onchange(true);
33
+ this.__check(version);
34
+ }
35
+ //...
36
+ /**
37
+ * Добавляет промис в очередь отслеживания
38
+ *
39
+ * @example
40
+ * ```typescript
41
+ * async function fetchData() {
42
+ * const promise = fetch("/api/data");
43
+ * loader.push(promise);
44
+ * const data = await promise;
45
+ * return data;
46
+ * }
47
+ * ```
48
+ */
49
+ push(promise) {
50
+ this.__version++;
51
+ this.__heap.push(promise);
52
+ this.__awaiter(this.__version);
53
+ }
54
+ /**
55
+ * Создаёт хук: возвращает функцию, которая завершает отслеживание при вызове
56
+ *
57
+ * Внутри создаётся промис, добавляемый в очередь. Вызов возвращённой функции разрешает его
58
+ *
59
+ * @example
60
+ * ```typescript
61
+ * const complete = loader.hook();
62
+ * try {
63
+ * await someAsyncOperation();
64
+ * } finally {
65
+ * complete();
66
+ * }
67
+ * ```
68
+ */
69
+ hook() {
70
+ const { promise, resolve } = createManualPromise();
71
+ this.push(promise);
72
+ return resolve;
73
+ }
74
+ /**
75
+ * Выполняет функцию и автоматически отслеживает её промис
76
+ *
77
+ * @param func — Асинхронная функция для выполнения
78
+ * @param [external] — Опциональный коллбэк для синхронного уведомления о начале/завершении
79
+ *
80
+ * @throws {unknown} Ошибки промиса функции
81
+ *
82
+ * @example
83
+ * ```typescript
84
+ * async function fetchData() {
85
+ * const data = await loader.run(() => fetch("/api/data"));
86
+ * return data;
87
+ * }
88
+ * ```
89
+ */
90
+ async run(func, external) {
91
+ external?.(true);
92
+ try {
93
+ const promise = func();
94
+ this.push(promise);
95
+ return await promise;
96
+ }
97
+ finally {
98
+ external?.(false);
99
+ }
100
+ }
101
+ }
@@ -0,0 +1,51 @@
1
+ import type { CanBePromise, TimeoutType } from "../types.js";
2
+ export type QueueHandler<T> = (item: T, abort: () => void) => CanBePromise;
3
+ /**
4
+ * Асинхронная очередь с последовательной обработкой и возможностью прерывания
5
+ *
6
+ * Элементы обрабатываются **по одному**, с заданной задержкой между ними.
7
+ * Обработка останавливается, если очередь пуста, и возобновляется при новом `push`.
8
+ * Функция-обработчик получает `abort`, чтобы прервать дальнейшую обработку (например, при ошибке).
9
+ *
10
+ * @template T - Тип элементов в очереди
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * const queue = new Queue(async (url, abort) => {
15
+ * try {
16
+ * await fetch(url);
17
+ * } catch (e) {
18
+ * abort(); // прекращает обработку оставшихся URL
19
+ * }
20
+ * }, 50);
21
+ *
22
+ * queue.push("https://example.com/1");
23
+ * queue.push("https://example.com/2");
24
+ * ```
25
+ */
26
+ export declare class Queue<T> {
27
+ delay: number;
28
+ __queue: T[];
29
+ __timeout: TimeoutType | 0;
30
+ __handle: QueueHandler<T>;
31
+ /**
32
+ * @param handle - Основная функция для обработки очереди
33
+ * @param [delay=25] - Задержка (в миллисекундах) между обработкой элементов очереди
34
+ */
35
+ constructor(handle: QueueHandler<T>, delay?: number);
36
+ /**
37
+ * Добавляет элемент в очередь и запускает обработку
38
+ *
39
+ * @param item - Элемент для добавления в очередь
40
+ * @param [run=true] - Запуск выполнения через {@link run}
41
+ */
42
+ push(item: T, run?: boolean): void;
43
+ /**
44
+ * @param [delay=this.delay] - Задержка перед запуском шага очереди
45
+ *
46
+ * @remarks Саморекурсивно
47
+ */
48
+ run(delay?: number): void;
49
+ stop(): void;
50
+ reset(): void;
51
+ }
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Асинхронная очередь с последовательной обработкой и возможностью прерывания
3
+ *
4
+ * Элементы обрабатываются **по одному**, с заданной задержкой между ними.
5
+ * Обработка останавливается, если очередь пуста, и возобновляется при новом `push`.
6
+ * Функция-обработчик получает `abort`, чтобы прервать дальнейшую обработку (например, при ошибке).
7
+ *
8
+ * @template T - Тип элементов в очереди
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * const queue = new Queue(async (url, abort) => {
13
+ * try {
14
+ * await fetch(url);
15
+ * } catch (e) {
16
+ * abort(); // прекращает обработку оставшихся URL
17
+ * }
18
+ * }, 50);
19
+ *
20
+ * queue.push("https://example.com/1");
21
+ * queue.push("https://example.com/2");
22
+ * ```
23
+ */
24
+ export class Queue {
25
+ delay;
26
+ __queue = [];
27
+ __timeout = 0;
28
+ __handle;
29
+ /**
30
+ * @param handle - Основная функция для обработки очереди
31
+ * @param [delay=25] - Задержка (в миллисекундах) между обработкой элементов очереди
32
+ */
33
+ constructor(handle, delay = 25) {
34
+ this.__handle = handle;
35
+ this.delay = delay;
36
+ }
37
+ /**
38
+ * Добавляет элемент в очередь и запускает обработку
39
+ *
40
+ * @param item - Элемент для добавления в очередь
41
+ * @param [run=true] - Запуск выполнения через {@link run}
42
+ */
43
+ push(item, run = true) {
44
+ this.__queue.push(item);
45
+ if (run)
46
+ this.run();
47
+ }
48
+ /**
49
+ * @param [delay=this.delay] - Задержка перед запуском шага очереди
50
+ *
51
+ * @remarks Саморекурсивно
52
+ */
53
+ run(delay = this.delay) {
54
+ this.stop();
55
+ const start = async () => {
56
+ if (this.__queue.length === 0)
57
+ return this.stop();
58
+ const item = this.__queue.shift();
59
+ let aborted = false;
60
+ try {
61
+ await this.__handle(item, () => (aborted = true));
62
+ }
63
+ finally {
64
+ if (!aborted)
65
+ this.__queue.length > 0 ? this.run() : this.stop();
66
+ }
67
+ };
68
+ if (delay) {
69
+ this.__timeout = setTimeout(() => void start(), delay);
70
+ }
71
+ else {
72
+ void start();
73
+ }
74
+ }
75
+ stop() {
76
+ if (this.__timeout)
77
+ clearTimeout(this.__timeout);
78
+ this.__timeout = 0;
79
+ }
80
+ reset() {
81
+ this.stop();
82
+ this.__queue.length = 0;
83
+ }
84
+ }
package/dist/cases.d.ts CHANGED
@@ -1,30 +1,40 @@
1
- export type CaseResult<V, T> = (value: V | undefined, mutate: boolean) => T;
2
1
  /**
3
- * Отлов строковых значений
2
+ * Результат обработки значения в case-функциях
4
3
  *
5
- * - `string` `string`, `false`
6
- * - `number` `string`, `true`
7
- * - `NaN` → `undefined`, `false`
8
- * - `ETC` `undefined`, `false`
4
+ * @template V - Тип преобразованного значения
5
+ * @template T - Тип возвращаемого значения
6
+ *
7
+ * @param value - Преобразованное значение или undefined если преобразование невозможно
8
+ * @param mutated - Флаг указывающий было ли значение преобразовано (true) или осталось исходным (false)
9
+ */
10
+ export type CaseResult<V, T> = (value: V | undefined, mutated: boolean) => T;
11
+ /**
12
+ * Преобразует значение к строке
13
+ *
14
+ * - `string` → исходная строка, `mutated: false`
15
+ * - `number` → строка, `mutated: true`
16
+ * - `NaN` → `undefined`, `mutated: false`
17
+ * - `ETC` → `undefined`, `mutated: false`
9
18
  */
10
- export declare const caseString: <T>(value: unknown, call: CaseResult<string, T>) => T;
19
+ export declare const caseString: <T>(value: unknown, callback: CaseResult<string, T>) => T;
11
20
  /**
12
- * Отлов числовых значений
21
+ * Преобразует значение к числу
13
22
  *
14
- * - `number` → `number`, `false`
15
- * - `string` → `number`, `true`
16
- * - `NaN` → `undefined`, `false`
17
- * - `ETC` → `undefined`, `false`
23
+ * - `number` (не NaN) исходное число, `mutated: false`
24
+ * - `string` (числовая строка) число, `mutated: true`
25
+ * - `number` (NaN) → `undefined`, `mutated: false`
26
+ * - `string` (пустая или нечисловая) → `undefined`, `mutated: false`
27
+ * - `ETC` → `undefined`, `mutated: false`
18
28
  */
19
- export declare const caseNumber: <T>(value: unknown, call: CaseResult<number, T>) => T;
29
+ export declare const caseNumber: <T>(value: unknown, callback: CaseResult<number, T>) => T;
20
30
  /**
21
- * Отлов булевых значений
31
+ * Преобразует значение к булеву типу
22
32
  *
23
- * - `boolean` -> `boolean`, `false`
24
- * - `"false"` -> `boolean`, `true`
25
- * - `"true"` -> `boolean`, `true`
26
- * - `0` -> `boolean`, `true`
27
- * - `1` -> `boolean`, `true`
28
- * - `ETC` → `undefined`, `false`
33
+ * - `boolean` исходное значение, `mutated: false`
34
+ * - `number` (0) `false`, `mutated: true`
35
+ * - `number` (1) `true`, `mutated: true`
36
+ * - `string` ("false") `false`, `mutated: true`
37
+ * - `string` ("true") `true`, `mutated: true`
38
+ * - `ETC` → `undefined`, `mutated: false`
29
39
  */
30
- export declare const caseBoolean: <T>(value: unknown, call: CaseResult<boolean, T>) => T;
40
+ export declare const caseBoolean: <T>(value: unknown, callback: CaseResult<boolean, T>) => T;
package/dist/cases.js CHANGED
@@ -1,69 +1,73 @@
1
1
  /**
2
- * Отлов строковых значений
2
+ * Преобразует значение к строке
3
3
  *
4
- * - `string` → `string`, `false`
5
- * - `number` → `string`, `true`
6
- * - `NaN` → `undefined`, `false`
7
- * - `ETC` → `undefined`, `false`
4
+ * - `string` → исходная строка, `mutated: false`
5
+ * - `number` → строка, `mutated: true`
6
+ * - `NaN` → `undefined`, `mutated: false`
7
+ * - `ETC` → `undefined`, `mutated: false`
8
8
  */
9
- export const caseString = (value, call) => {
9
+ export const caseString = (value, callback) => {
10
10
  switch (typeof value) {
11
11
  case "string":
12
- return call(value, false);
12
+ return callback(value, false);
13
13
  case "number":
14
14
  if (!isNaN(value))
15
- return call(String(value), true);
15
+ return callback(String(value), true);
16
16
  }
17
- return call(undefined, false);
17
+ return callback(undefined, false);
18
18
  };
19
19
  /**
20
- * Отлов числовых значений
20
+ * Преобразует значение к числу
21
21
  *
22
- * - `number` → `number`, `false`
23
- * - `string` → `number`, `true`
24
- * - `NaN` → `undefined`, `false`
25
- * - `ETC` → `undefined`, `false`
22
+ * - `number` (не NaN) исходное число, `mutated: false`
23
+ * - `string` (числовая строка) число, `mutated: true`
24
+ * - `number` (NaN) → `undefined`, `mutated: false`
25
+ * - `string` (пустая или нечисловая) → `undefined`, `mutated: false`
26
+ * - `ETC` → `undefined`, `mutated: false`
26
27
  */
27
- export const caseNumber = (value, call) => {
28
+ export const caseNumber = (value, callback) => {
28
29
  switch (typeof value) {
29
30
  case "number":
30
- return call(isNaN(value) ? undefined : value, false);
31
+ return callback(isNaN(value) ? undefined : value, false);
31
32
  case "string": {
32
33
  const trimmed = value.trim();
33
- const number = Number(trimmed);
34
- if (!isNaN(number) && value !== "")
35
- return call(number, true);
34
+ // Проверяем что строка не пустая и преобразуется в валидное число
35
+ if (trimmed !== "") {
36
+ const number = Number(trimmed);
37
+ if (!isNaN(number))
38
+ return callback(number, true);
39
+ }
36
40
  }
37
41
  }
38
- return call(undefined, false);
42
+ return callback(undefined, false);
39
43
  };
40
44
  /**
41
- * Отлов булевых значений
45
+ * Преобразует значение к булеву типу
42
46
  *
43
- * - `boolean` -> `boolean`, `false`
44
- * - `"false"` -> `boolean`, `true`
45
- * - `"true"` -> `boolean`, `true`
46
- * - `0` -> `boolean`, `true`
47
- * - `1` -> `boolean`, `true`
48
- * - `ETC` → `undefined`, `false`
47
+ * - `boolean` исходное значение, `mutated: false`
48
+ * - `number` (0) `false`, `mutated: true`
49
+ * - `number` (1) `true`, `mutated: true`
50
+ * - `string` ("false") `false`, `mutated: true`
51
+ * - `string` ("true") `true`, `mutated: true`
52
+ * - `ETC` → `undefined`, `mutated: false`
49
53
  */
50
- export const caseBoolean = (value, call) => {
54
+ export const caseBoolean = (value, callback) => {
51
55
  switch (typeof value) {
52
56
  case "boolean":
53
- return call(value, false);
57
+ return callback(value, false);
54
58
  case "number":
55
59
  if (value === 0)
56
- return call(false, true);
60
+ return callback(false, true);
57
61
  if (value === 1)
58
- return call(true, true);
62
+ return callback(true, true);
59
63
  break;
60
64
  case "string": {
61
- const flat = value.trim().toLowerCase();
62
- if (flat === "false")
63
- return call(false, true);
64
- if (flat === "true")
65
- return call(true, true);
65
+ const normalized = value.trim().toLowerCase();
66
+ if (normalized === "false")
67
+ return callback(false, true);
68
+ if (normalized === "true")
69
+ return callback(true, true);
66
70
  }
67
71
  }
68
- return call(undefined, false);
72
+ return callback(undefined, false);
69
73
  };