@reforgium/internal 1.1.0 → 1.1.1

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.
@@ -76,12 +76,12 @@ const VALIDATION_MESSAGES = new InjectionToken('RE_VALIDATION_MESSAGES', {
76
76
  });
77
77
 
78
78
  /**
79
- * Загружает файл из объекта Blob и предлагает пользователю сохранить его.
79
+ * Downloads a file from a Blob object and prompts the user to save it.
80
80
  *
81
- * @param {Blob} blob - Объект Blob, представляющий файл для загрузки.
82
- * @param {string} [fileName] - Опционально. Имя для загружаемого файла.
83
- * Если не указано, в качестве имени файла будет использоваться текущая метка времени.
84
- * @return {void} Не возвращает значение.
81
+ * @param {Blob} blob - Blob object representing the file to download.
82
+ * @param {string} [fileName] - Optional. Name for the downloaded file.
83
+ * If not specified, the current timestamp will be used as the filename.
84
+ * @return {void} Does not return a value.
85
85
  */
86
86
  function downloadByBlob(blob, fileName) {
87
87
  const win = window;
@@ -95,12 +95,12 @@ function downloadByBlob(blob, fileName) {
95
95
  }
96
96
  }
97
97
  /**
98
- * Инициирует загрузку файла по-указанному URL. Опционально можно указать пользовательское имя файла.
98
+ * Initiates a file download for the given URL. Optionally, a custom filename can be specified.
99
99
  *
100
- * @param {string} url - URL файла для загрузки.
101
- * @param {string} [filename] - Желаемое имя для загружаемого файла.
102
- * Если не указано, будет использовано имя на основе временной метки.
103
- * @return {void} Функция не возвращает значение.
100
+ * @param {string} url - URL of the file to download.
101
+ * @param {string} [filename] - Desired name for the downloaded file.
102
+ * If not specified, a timestamp-based name will be used.
103
+ * @return {void} The function does not return a value.
104
104
  */
105
105
  function downloadByUrl(url, filename) {
106
106
  const win = window;
@@ -114,12 +114,12 @@ function downloadByUrl(url, filename) {
114
114
  win.document.body.removeChild(a);
115
115
  }
116
116
  /**
117
- * Копирует указанный текст в буфер обмена. Использует Clipboard API, если доступен,
118
- * в противном случае использует `document.execCommand` в качестве запасного метода.
117
+ * Copies the specified text to the clipboard. Uses the Clipboard API if available,
118
+ * otherwise falls back to `document.execCommand`.
119
119
  *
120
- * @param {string} text - Текст, который необходимо скопировать в буфер обмена.
121
- * @return {Promise<boolean>} Промис, который резолвится в boolean, указывающий, было ли
122
- * копирование текста успешным.
120
+ * @param {string} text - The text to copy to the clipboard.
121
+ * @return {Promise<boolean>} A promise that resolves to a boolean indicating whether
122
+ * the text copying was successful.
123
123
  */
124
124
  async function copyText(text) {
125
125
  const win = window;
@@ -145,13 +145,13 @@ async function copyText(text) {
145
145
  return ok;
146
146
  }
147
147
  /**
148
- * Преобразует строку в формате Base64 в объект Blob.
148
+ * Converts a Base64 encoded string to a Blob object.
149
149
  *
150
- * @param {string} base64 - Строка в формате Base64. Может опционально включать MIME-тип
151
- * в формате `data:<mimeType>;base64,<data>`.
152
- * @param {string} [mimeType=''] - MIME-тип данных. Необязательный параметр, будет переопределен,
153
- * если `base64` включает MIME-тип.
154
- * @return {Blob} Объект Blob, созданный из строки в формате Base64.
150
+ * @param {string} base64 - Base64 encoded string. Can optionally include a MIME type
151
+ * in the format `data:<mimeType>;base64,<data>`.
152
+ * @param {string} [mimeType=''] - MIME type of the data. Optional parameter, will be overridden
153
+ * if the `base64` string includes a MIME type.
154
+ * @return {Blob} A Blob object created from the Base64 string.
155
155
  */
156
156
  function base64ToBlob(base64, mimeType = '') {
157
157
  const matches = base64.match(/^data:(.+);base64,(.*)$/);
@@ -166,6 +166,27 @@ function base64ToBlob(base64, mimeType = '') {
166
166
  return new Blob([byteArray], { type: mime });
167
167
  }
168
168
 
169
+ /**
170
+ * Creates a debounced signal that delays updates from the source signal.
171
+ * The output signal will only update after the specified delay has passed without new values.
172
+ *
173
+ * @template T - The type of the signal value
174
+ * @param {Signal<T>} src - The source signal to debounce
175
+ * @param {number} [ms=150] - The debounce delay in milliseconds (default: 150ms)
176
+ * @param {Object} [opts] - Optional configuration
177
+ * @param {Injector} [opts.injector] - Optional injector for the effect context
178
+ * @returns {Signal<T>} A readonly signal that emits debounced values from the source
179
+ *
180
+ * @example
181
+ * ```typescript
182
+ * const searchQuery = signal('');
183
+ * const debouncedQuery = debounceSignal(searchQuery, 300);
184
+ *
185
+ * effect(() => {
186
+ * console.log('Debounced value:', debouncedQuery());
187
+ * });
188
+ * ```
189
+ */
169
190
  const debounceSignal = (src, ms = 150, opts) => {
170
191
  const out = signal(src(), ...(ngDevMode ? [{ debugName: "out" }] : []));
171
192
  let timeoutRef;
@@ -182,6 +203,29 @@ const debounceSignal = (src, ms = 150, opts) => {
182
203
  }, { injector: opts?.injector });
183
204
  return out.asReadonly();
184
205
  };
206
+ /**
207
+ * Creates a throttled signal that limits the rate of updates from the source signal.
208
+ * The output signal will emit the first value immediately, then wait for the specified delay
209
+ * before allowing subsequent updates. If values are emitted during the waiting period,
210
+ * the last value will be queued and emitted after the delay.
211
+ *
212
+ * @template T - The type of the signal value
213
+ * @param {Signal<T>} src - The source signal to throttle
214
+ * @param {number} [ms=100] - The throttle delay in milliseconds (default: 100ms)
215
+ * @param {Object} [opts] - Optional configuration
216
+ * @param {Injector} [opts.injector] - Optional injector for the effect context
217
+ * @returns {Signal<T>} A readonly signal that emits throttled values from the source
218
+ *
219
+ * @example
220
+ * ```typescript
221
+ * const scrollPosition = signal(0);
222
+ * const throttledPosition = throttleSignal(scrollPosition, 200);
223
+ *
224
+ * effect(() => {
225
+ * console.log('Throttled position:', throttledPosition());
226
+ * });
227
+ * ```
228
+ */
185
229
  const throttleSignal = (src, ms = 100, opts) => {
186
230
  const out = signal(src(), ...(ngDevMode ? [{ debugName: "out" }] : []));
187
231
  let last = 0;
@@ -227,19 +271,19 @@ const throttleSignal = (src, ms = 100, opts) => {
227
271
 
228
272
  const pad = (n) => n.toString().padStart(2, '0');
229
273
  /**
230
- * Форматирует объект даты в строку заданного формата.
274
+ * Formats a Date object into a string of the given format.
231
275
  *
232
- * @param {Date} date - Объект даты для форматирования.
233
- * @param {string} [format='yyyy-MM-dd'] - Строковый формат для применения. По умолчанию 'yyyy-MM-dd'.
234
- * Поддерживаемые токены в строке формата:
235
- * - yyyy: Полный год (например, 2023)
236
- * - MM: Месяц с ведущим нулем (01-12)
237
- * - dd: День месяца с ведущим нулем (01-31)
238
- * - HH: Час в 24-часовом формате с ведущим нулем (00-23)
239
- * - mm: Минуты с ведущим нулем (00-59)
240
- * - ss: Секунды с ведущим нулем (00-59)
276
+ * @param {Date} date - Date object to format.
277
+ * @param {string} [format='yyyy-MM-dd'] - String format to apply. Defaults to 'yyyy-MM-dd'.
278
+ * Supported tokens in the format string:
279
+ * - yyyy: Full year (e.g., 2023)
280
+ * - MM: Month with leading zero (01-12)
281
+ * - dd: Day of the month with leading zero (01-31)
282
+ * - HH: Hour in 24-hour format with leading zero (00-23)
283
+ * - mm: Minutes with leading zero (00-59)
284
+ * - ss: Seconds with leading zero (00-59)
241
285
  *
242
- * @returns {string} Отформатированная строка даты. Возвращает пустую строку, если входная дата некорректна.
286
+ * @returns {string} Formatted date string. Returns an empty string if the input date is invalid.
243
287
  */
244
288
  const formatDate = (date, format = 'yyyy-MM-dd') => {
245
289
  if (isNaN(date['getTime']?.())) {
@@ -260,11 +304,11 @@ const formatDate = (date, format = 'yyyy-MM-dd') => {
260
304
  return formatted;
261
305
  };
262
306
  /**
263
- * Форматирует заданную дату в локализованную строковую репрезентацию в формате 'день месяц год'.
264
- * Месяц локализован для 'ru-RU' локали и сокращен.
307
+ * Formats the given date into a localized string representation in the format 'day month year'.
308
+ * The month is localized for 'ru-RU' locale and abbreviated.
265
309
  *
266
- * @param {Date} date - Объект даты для форматирования.
267
- * @return {string} Строка, представляющая отформатированную дату в формате 'день месяц год'.
310
+ * @param {Date} date - Date object to format.
311
+ * @return {string} A string representing the formatted date in the format 'day month year'.
268
312
  */
269
313
  function formatToLocaledDate(date) {
270
314
  const day = date.getDate();
@@ -273,12 +317,12 @@ function formatToLocaledDate(date) {
273
317
  return `${day} ${month} ${year}`;
274
318
  }
275
319
  /**
276
- * Парсит дату из строки по заданной маске.
277
- * Поддерживает dd, MM, yyyy, HH, mm, ss.
278
- * Разделители любые: '.', '/', '-',' '.
320
+ * Parses a date from a string based on the given mask.
321
+ * Supports dd, MM, yyyy, HH, mm, ss.
322
+ * Any delimiters: '.', '/', '-', ' '.
279
323
  *
280
- * @param {string} value - исходная строка с датой
281
- * @param {string} format - маска, например "dd.MM.yyyy"
324
+ * @param {string} value - source date string
325
+ * @param {string} format - mask, e.g., "dd.MM.yyyy"
282
326
  * @returns {Date|null}
283
327
  */
284
328
  const parseToDate = (value, format = 'dd.MM.yyyy') => {
@@ -307,19 +351,19 @@ const parseToDate = (value, format = 'dd.MM.yyyy') => {
307
351
  return date;
308
352
  };
309
353
  /**
310
- * Парсит строковое представление двух дат в кортеж объектов `Date` или значений `null`.
354
+ * Parses a string representation of two dates into a tuple of `Date` objects or `null` values.
311
355
  *
312
- * Эта функция пытается извлечь и разобрать два значения даты из входной строки
313
- * на основе предоставленного формата даты. Если парсинг неуспешен, возвращаемый кортеж будет
314
- * состоять из значений `null`. По умолчанию ожидаемый формат даты - `dd.MM.yyyy`, но он
315
- * может быть изменен.
356
+ * This function attempts to extract and parse two date values from the input string
357
+ * based on the provided date format. If parsing is unsuccessful, the returned tuple will
358
+ * consist of `null` values. The default expected date format is `dd.MM.yyyy`, but it
359
+ * can be changed.
316
360
  *
317
- * @param {string | null} value - Строка, содержащая представления дат для разбора.
318
- * Если `null`, функция вернет `[null, null]`.
319
- * @param {string} [format='dd.MM.yyyy'] - Формат даты, используемый для парсинга.
320
- * Поддерживает `yyyy`, `MM`, `dd`, `HH`, `mm` и `ss`.
321
- * @returns {[Date | null, Date | null]} Кортеж, где первый элемент - разобранная начальная дата
322
- * и второй элемент - разобранная конечная дата. Если парсинг не удался, оба элемента будут `null`.
361
+ * @param {string | null} value - String containing date representations to parse.
362
+ * If `null`, the function will return `[null, null]`.
363
+ * @param {string} [format='dd.MM.yyyy'] - Date format used for parsing.
364
+ * Supports `yyyy`, `MM`, `dd`, `HH`, `mm`, and `ss`.
365
+ * @returns {[Date | null, Date | null]} A tuple where the first element is the parsed start date
366
+ * and the second element is the parsed end date. If parsing fails, both elements will be `null`.
323
367
  */
324
368
  const parseToDatePeriod = (value, format = 'dd.MM.yyyy') => {
325
369
  if (typeof value !== 'string' || !format) {
@@ -344,21 +388,21 @@ const parseToDatePeriod = (value, format = 'dd.MM.yyyy') => {
344
388
  }
345
389
  };
346
390
  /**
347
- * Определяет, является ли переданное значение периодом дат.
391
+ * Determines if the given value is a date period.
348
392
  *
349
- * Период дат представляется в виде массива, содержащего ровно два экземпляра Date.
350
- * Оба элемента массива должны быть корректными объектами Date (т.е. не `Invalid Date`).
393
+ * A date period is represented as an array containing exactly two Date instances.
394
+ * Both elements of the array must be valid Date objects (i.e., not `Invalid Date`).
351
395
  *
352
- * @param {unknown} value - Значение для проверки.
353
- * @returns {value is [Date, Date]} - Возвращает `true`, если значение является корректным периодом дат, иначе `false`.
396
+ * @param {unknown} value - Value to check.
397
+ * @returns {value is [Date, Date]} - Returns `true` if the value is a valid date period, otherwise `false`.
354
398
  */
355
399
  const isDatePeriod = (value) => Array.isArray(value) && value.length === 2 && value.every((it) => it instanceof Date && !isNaN(it.getTime()));
356
400
  /**
357
- * Преобразует различные типы данных в объект Date.
401
+ * Converts various data types to a Date object.
358
402
  *
359
- * @param {unknown} v - Значение для преобразования. Может быть объектом Date,
360
- * числом (timestamp) или строкой, содержащей корректную дату.
361
- * @returns {Date} Объект Date. Если преобразование невозможно, возвращает Invalid Date.
403
+ * @param {unknown} v - Value to convert. Can be a Date object,
404
+ * a number (timestamp), or a string containing a valid date.
405
+ * @returns {Date} Date object. If conversion is impossible, returns Invalid Date.
362
406
  */
363
407
  const toDate = (v) => {
364
408
  if (v instanceof Date)
@@ -370,8 +414,8 @@ const toDate = (v) => {
370
414
  return new Date(NaN);
371
415
  };
372
416
  /**
373
- * Переводит строку даты из заданного формата в ISO (UTC).
374
- * Пример:
417
+ * Converts a date string from a given format to ISO (UTC).
418
+ * Example:
375
419
  * reformatDateToISO("24.11.2025", "dd.MM.yyyy")
376
420
  * → "2025-11-24T00:00:00.000Z"
377
421
  */
@@ -421,27 +465,27 @@ function reformatDateToISO(dateStr, mask) {
421
465
  }
422
466
 
423
467
  /**
424
- * Определяет, является ли переданное значение null или undefined, опционально учитывая
425
- * пустые строки как null-подобные значения.
468
+ * Determines if the given value is null or undefined, optionally considering
469
+ * empty strings as null-like values.
426
470
  *
427
- * @param {unknown} value - Значение для проверки на null или undefined.
428
- * @param {boolean} [withEmptyString=false] - Если true, пустые строки также считаются
429
- * null-подобными значениями в дополнение к null и undefined.
430
- * @returns {value is null | undefined} Возвращает `true`, если значение равно null, undefined,
431
- * или (если `withEmptyString` равно true) пустой строке. В противном случае возвращает `false`.
471
+ * @param {unknown} value - Value to check for null or undefined.
472
+ * @param {boolean} [withEmptyString=false] - If true, empty strings are also considered
473
+ * null-like values in addition to null and undefined.
474
+ * @returns {value is null | undefined} Returns `true` if the value is null, undefined,
475
+ * or (if `withEmptyString` is true) an empty string. Otherwise returns `false`.
432
476
  */
433
477
  const isNullable = (value, withEmptyString = false) => value === null || value === undefined || (withEmptyString ? value === '' : false);
434
478
  /**
435
- * Проверяет, является ли переданное значение числом или может быть преобразовано в корректное число.
479
+ * Checks if the given value is a number or can be converted to a valid number.
436
480
  *
437
- * Эта функция проверяет, является ли входное значение числовым. Если входное значение
438
- * имеет тип number, проверяется, что оно является конечным числом и не NaN. Если входное
439
- * значение является строкой, проверяется возможность преобразования этой строки в корректное число.
481
+ * This function checks if the input value is numeric. If the input value
482
+ * is of type number, it is verified to be a finite number and not NaN. If the input
483
+ * value is a string, it checks if this string can be converted to a valid number.
440
484
  *
441
- * @param {unknown} value - Значение для проверки.
442
- * @param {boolean} [fromString=false] - Если true, строковые значения будут пытаться преобразоваться в число.
443
- * @returns {value is number} `true` если значение является числом или строкой,
444
- * которую можно преобразовать в число; иначе `false`.
485
+ * @param {unknown} value - Value to check.
486
+ * @param {boolean} [fromString=false] - If true, string values will attempt to be converted to a number.
487
+ * @returns {value is number} `true` if the value is a number or a string
488
+ * that can be converted to a number; otherwise `false`.
445
489
  */
446
490
  const isNumber = (value, fromString = false) => {
447
491
  if (typeof value === 'number') {
@@ -531,12 +575,12 @@ const concatArray = (value, mode, key) => {
531
575
  };
532
576
 
533
577
  /**
534
- * Форматирует число или строку, содержащую число, добавляя пробелы в качестве разделителей тысяч.
578
+ * Formats a number or a string containing a number by adding spaces as thousands separators.
535
579
  *
536
- * @param {number|string} num - Число или строка для форматирования.
537
- * Если входное значение null, undefined или недопустимое число, возвращается пустая строка.
538
- * @return {string} Отформатированная строка с пробелами в качестве разделителей тысяч или пустая строка,
539
- * если входные данные недопустимы.
580
+ * @param {number|string} num - The number or string to format.
581
+ * If the input value is null, undefined, or an invalid number, an empty string is returned.
582
+ * @return {string} Formatted string with spaces as thousands separators, or an empty string
583
+ * if the input is invalid.
540
584
  */
541
585
  function formatToSpacedNumber(num) {
542
586
  const stringed = String(num).replaceAll(' ', '');
@@ -547,13 +591,13 @@ function formatToSpacedNumber(num) {
547
591
  return str.replace(/\B(?=(\d{3})+(?!\d))/g, ' ');
548
592
  }
549
593
  /**
550
- * Обрезает строку до указанного количества символов и добавляет многоточие ('…'),
551
- * если строка превышает лимит.
594
+ * Truncates a string to the specified number of characters and adds an ellipsis ('…')
595
+ * if the string exceeds the limit.
552
596
  *
553
- * @param {string} text - Текст для обрезки.
554
- * @param {number} limit - Максимально допустимая длина строки.
555
- * @returns {string} Обрезанная строка с многоточием, если длина превышает лимит,
556
- * или исходная строка, если нет.
597
+ * @param {string} text - The text to truncate.
598
+ * @param {number} limit - Maximum allowed string length.
599
+ * @returns {string} Truncated string with an ellipsis if length exceeds the limit,
600
+ * or the original string otherwise.
557
601
  */
558
602
  const truncate = (text, limit) => {
559
603
  return text.length > limit ? text.slice(0, limit) + '…' : text;
@@ -614,12 +658,12 @@ const getDirMap = (directions) => {
614
658
  };
615
659
 
616
660
  /**
617
- * Вычисляет доступное вертикальное пространство под заданным элементом в области просмотра.
661
+ * Calculates the available vertical space below the given element in the viewport.
618
662
  *
619
- * @param {Element} el - DOM элемент, для которого необходимо вычислить доступную высоту снизу.
620
- * @param {number} [margin=20] - Опциональное поле, вычитаемое из вычисленной доступной высоты.
621
- * @return {number} Доступная высота в пикселях под элементом с учетом поля.
622
- * Возвращает 0, если нет доступного пространства.
663
+ * @param {Element} el - DOM element for which to calculate the available height below.
664
+ * @param {number} [margin=20] - Optional margin subtracted from the calculated available height.
665
+ * @return {number} Available height in pixels below the element, taking margin into account.
666
+ * Returns 0 if there is no available space.
623
667
  */
624
668
  function getAvailableHeight(el, margin = 20) {
625
669
  const rect = el.getBoundingClientRect();
@@ -630,12 +674,12 @@ function getAvailableHeight(el, margin = 20) {
630
674
  }
631
675
 
632
676
  /**
633
- * Извлекает значение по вложенному пути внутри объекта или массива.
634
- * Путь указывается в виде строки с разделителями-точками.
677
+ * Retrieves a value by a nested path within an object or array.
678
+ * The path is specified as a dot-delimited string.
635
679
  *
636
- * @param obj Объект или массив для обхода.
637
- * @param path Строка с разделителями-точками, указывающая путь для извлечения значения.
638
- * @return Значение, найденное по указанному пути, или undefined, если путь не существует или недействителен.
680
+ * @param obj The object or array to traverse.
681
+ * @param path A dot-delimited string specifying the path to retrieve the value.
682
+ * @return The value found at the specified path, or undefined if the path does not exist or is invalid.
639
683
  */
640
684
  function getChainedValue(obj, path) {
641
685
  if (!obj) {
@@ -657,11 +701,11 @@ function getChainedValue(obj, path) {
657
701
  }
658
702
 
659
703
  /**
660
- * Нормализует заданный URL, удаляя избыточные слеши, разрешая сегменты с точками
661
- * и обеспечивая отсутствие завершающих слешей в конце URL.
704
+ * Normalizes a given URL by removing redundant slashes, resolving dot segments,
705
+ * and ensuring there are no trailing slashes at the end of the URL.
662
706
  *
663
- * @param {string} url - Строка URL для нормализации.
664
- * @return {string} - Нормализованная строка URL.
707
+ * @param {string} url - The URL string to normalize.
708
+ * @return {string} - The normalized URL string.
665
709
  */
666
710
  function normalizeUrl(url) {
667
711
  const [protocol, rest] = url.split('://');
@@ -672,14 +716,14 @@ function normalizeUrl(url) {
672
716
  return rest ? `${protocol}://${cleaned}` : cleaned;
673
717
  }
674
718
  /**
675
- * Заменяет заполнители в предоставленном URL-шаблоне соответствующими значениями из объекта params.
676
- * Заполнители определяются как `:key` в строке шаблона.
719
+ * Replaces placeholders in the provided URL template with corresponding values from the params object.
720
+ * Placeholders are defined as `:key` in the template string.
677
721
  *
678
- * @param {string} template URL-шаблон, содержащий заполнители для замены.
679
- * @param {AnyDict} [params] Опциональный словарь, содержащий пары ключ-значение.
680
- * Ключи соответствуют заполнителям в шаблоне, а значения заменят их.
681
- * @return {string} URL с заполнителями, замененными соответствующими значениями из объекта params.
682
- * По умолчанию возвращает исходный шаблон, если params не предоставлен.
722
+ * @param {string} template URL template containing placeholders to replace.
723
+ * @param {AnyDict} [params] Optional dictionary containing key-value pairs.
724
+ * Keys correspond to placeholders in the template, and values will replace them.
725
+ * @return {string} URL with placeholders replaced by corresponding values from the params object.
726
+ * Defaults to the original template if params is not provided.
683
727
  */
684
728
  function fillUrlWithParams(template, params) {
685
729
  if (!params) {
@@ -688,12 +732,12 @@ function fillUrlWithParams(template, params) {
688
732
  return template.replace(/:([a-zA-Z0-9_]+)/g, (_, k) => encodeURIComponent(params[k] ?? ''));
689
733
  }
690
734
  /**
691
- * Добавляет параметры запроса к указанному URL.
735
+ * Appends query parameters to the specified URL.
692
736
  *
693
- * @param {string} url Базовый URL, к которому будут добавлены параметры запроса.
694
- * @param {Record<string, unknown>} [params] Опциональный объект, содержащий пары ключ-значение параметров запроса.
695
- * Ключи со значениями null или undefined будут проигнорированы.
696
- * @return {string} URL с добавленными параметрами запроса.
737
+ * @param {string} url Base URL to which query parameters will be added.
738
+ * @param {Record<string, unknown>} [params] Optional object containing query parameter key-value pairs.
739
+ * Keys with null or undefined values will be ignored.
740
+ * @return {string} URL with appended query parameters.
697
741
  */
698
742
  function appendQueryParams(url, params) {
699
743
  if (!params || !Object.keys(params).length)
@@ -708,11 +752,11 @@ function appendQueryParams(url, params) {
708
752
  return `${base}?${searchParams.toString()}`;
709
753
  }
710
754
  /**
711
- * Разбирает строку запроса в объект, содержащий пары ключ-значение.
755
+ * Parses a query string into an object containing key-value pairs.
712
756
  *
713
- * @param {string} query - Строка запроса для разбора. Может начинаться с '?'.
714
- * @return {Record<string, string>} Объект, где каждый ключ - это имя параметра запроса,
715
- * а значение - соответствующее значение.
757
+ * @param {string} query - The query string to parse. May start with '?'.
758
+ * @return {Record<string, string>} An object where each key is a query parameter name,
759
+ * and the value is the corresponding value.
716
760
  */
717
761
  function parseQueryParams(query) {
718
762
  const search = query.startsWith('?') ? query.slice(1) : query;
@@ -727,13 +771,13 @@ function parseQueryParams(query) {
727
771
  /**
728
772
  * Constructs a query string from a given object and concatenation type.
729
773
  *
730
- * @param {Record<string, any>} object - Объект с парами ключ-значение для преобразования в строку запроса.
731
- * Ключи представляют имена параметров, а значения - значения параметров.
732
- * @param {'comma' | 'json' | 'multi'} concatType - Метод обработки значений массива:
733
- * - 'comma': Объединяет элементы массива через запятую.
734
- * - 'json': Сериализует массив как JSON строку.
735
- * - 'multi': Создает несколько записей для элементов массива, где каждый связан с одним и тем же ключом.
736
- * @returns {string} - Сформированная строка запроса с закодированными как URI компоненты ключами и значениями.
774
+ * @param {Record<string, any>} object - Object with key-value pairs to convert into a query string.
775
+ * Keys represent parameter names, and values represent parameter values.
776
+ * @param {'comma' | 'json' | 'multi'} concatType - Method for handling array values:
777
+ * - 'comma': Joins array elements with a comma.
778
+ * - 'json': Serializes the array as a JSON string.
779
+ * - 'multi': Creates multiple entries for array elements, each associated with the same key.
780
+ * @returns {string} - Formed query string with keys and values encoded as URI components.
737
781
  */
738
782
  const makeQuery = (object, concatType) => {
739
783
  return Object.entries(object)
@@ -748,16 +792,16 @@ const makeQuery = (object, concatType) => {
748
792
  .join('&');
749
793
  };
750
794
  /**
751
- * Сравнивает два маршрута, чтобы определить, совпадает ли фактический маршрут с шаблоном маршрута.
752
- * Поддерживает статическое и динамическое сопоставление маршрутов с опциональным учетом подмаршрутов.
795
+ * Compares two routes to determine if the actual route matches the route template.
796
+ * Supports static and dynamic route matching with optional subroute consideration.
753
797
  *
754
- * @param {string} actualRoute - Фактический путь маршрута для сравнения.
755
- * @param {string} pureRoute - Шаблонный путь маршрута для сопоставления, который может включать заполнители
756
- * (например, `:id`).
757
- * @param {boolean} [withSubroute=false] - Определяет, разрешать ли сопоставление подмаршрутов. Если true,
758
- * actualRoute должен начинаться с заполненного pureRoute.
759
- * @return {boolean} Возвращает true, если фактический маршрут соответствует шаблонному
760
- * маршруту (и опциональному условию подмаршрута, если включено), в противном случае false.
798
+ * @param {string} actualRoute - Actual route path to compare.
799
+ * @param {string} pureRoute - Template route path to match, which may include placeholders
800
+ * (e.g., `:id`).
801
+ * @param {boolean} [withSubroute=false] - Determines whether to allow subroute matching. If true,
802
+ * actualRoute must start with the filled pureRoute.
803
+ * @return {boolean} Returns true if the actual route matches the template
804
+ * route (and optional subroute condition if enabled), otherwise false.
761
805
  */
762
806
  const compareRoutes = (actualRoute, pureRoute, withSubroute = false) => {
763
807
  if (!pureRoute.includes(':')) {
@@ -769,12 +813,12 @@ const compareRoutes = (actualRoute, pureRoute, withSubroute = false) => {
769
813
  }
770
814
  };
771
815
  /**
772
- * Обрабатывает и материализует путь маршрута путем декодирования и при необходимости замены параметров маршрута.
816
+ * Processes and materializes a route path by decoding and, if necessary, replacing route parameters.
773
817
  *
774
- * @param {string} actualRoute - Фактический путь маршрута, обычно предоставляемый
775
- * в качестве источника значений динамических параметров.
776
- * @param {string} pureRoute - Шаблон пути маршрута, может включать динамические сегменты, обозначенные `:`.
777
- * @returns {string} Полностью материализованный и декодированный путь маршрута.
818
+ * @param {string} actualRoute - Actual route path, usually provided
819
+ * as a source for dynamic parameter values.
820
+ * @param {string} pureRoute - Route path template, may include dynamic segments denoted by `:`.
821
+ * @returns {string} Fully materialized and decoded route path.
778
822
  */
779
823
  const materializeRoutePath = (actualRoute, pureRoute) => {
780
824
  if (!pureRoute.includes(':')) {
@@ -798,14 +842,14 @@ const fillRouteTemplate = (actualRoute, pureRoute) => {
798
842
  };
799
843
 
800
844
  /**
801
- * Рекурсивно проверяет равенство двух объектов, включая вложенные структуры и особые случаи,
802
- * такие как массивы, наборы, карты, даты и NaN.
845
+ * Recursively checks the equality of two objects, including nested structures and special cases
846
+ * such as arrays, sets, maps, dates, and NaN.
803
847
  *
804
- * @param {AnyType} a - Первый объект для сравнения.
805
- * @param {AnyType} b - Второй объект для сравнения.
806
- * @param {Map} [seen=new Map()] - Карта, используемая для обнаружения циклических ссылок
807
- * при глубокой проверке равенства.
808
- * @return {boolean} - Возвращает true, если объекты полностью равны, иначе возвращает false.
848
+ * @param {AnyType} a - The first object to compare.
849
+ * @param {AnyType} b - The second object to compare.
850
+ * @param {Map} [seen=new Map()] - A map used to detect cyclic references
851
+ * during deep equality check.
852
+ * @return {boolean} - Returns true if the objects are deeply equal, otherwise returns false.
809
853
  */
810
854
  function deepEqual(a, b, seen = new Map()) {
811
855
  if (a === b) {