@endge/utils 0.25.6 → 0.26.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.
@@ -1,9 +1,9 @@
1
1
  import { CollectionEntity, CollectionEvents } from './collection.types';
2
- import { ChangeNotifier } from '../events/ChangeNotifier';
2
+ import { Subscribable } from '../events/Subscribable';
3
3
  /**
4
4
  * Описывает ответственность Collection в архитектуре проекта.
5
5
  */
6
- export declare class Collection<T extends CollectionEntity> extends ChangeNotifier {
6
+ export declare class Collection<T extends CollectionEntity> extends Subscribable {
7
7
  private _items;
8
8
  private _indices;
9
9
  private _rootIds;
@@ -0,0 +1,12 @@
1
+ /** Минимальный framework-independent contract объекта с подпиской на изменения. */
2
+ export interface SubscribableLike {
3
+ subscribe: (listener: () => void) => () => void;
4
+ }
5
+ /** Публикует изменения владельца состояния без зависимости от UI framework. */
6
+ export declare class Subscribable implements SubscribableLike {
7
+ private readonly _subscribers;
8
+ /** Подписывает listener и возвращает идемпотентную функцию отписки. */
9
+ subscribe(listener: () => void): () => void;
10
+ /** Уведомляет текущих подписчиков об изменении владельца состояния. */
11
+ notify(): void;
12
+ }
package/dist/index.d.ts CHANGED
@@ -4,6 +4,7 @@ export * from './collection/indexed-collection';
4
4
  export * from './collection/RingBuffer';
5
5
  export * from './database/PayloadHttpClient';
6
6
  export * from './events/EventBus';
7
+ export * from './events/Subscribable';
7
8
  export * from './execute/delay-executor';
8
9
  export * from './execute/NamedExecutor';
9
10
  export * from './serialize/decorators/json';
@@ -15,8 +16,8 @@ export * from './serialize/decorators/typeRecord';
15
16
  export * from './serialize/Serialize';
16
17
  export * from './shared/serialize/decorator';
17
18
  export { toInstance, toPlain } from './shared/serialize/parse';
18
- export { isNullOrUndefined } from './shared/types/maybe';
19
- export type { Maybe as SharedMaybe } from './shared/types/maybe';
19
+ export { isNullOrUndefined } from './shared/types/Maybe';
20
+ export type { Maybe as SharedMaybe } from './shared/types/Maybe';
20
21
  export * from './tools/compare';
21
22
  export * from './tools/console';
22
23
  export * from './tools/debug';
@@ -1,3 +1,3 @@
1
- import { Maybe } from './maybe';
1
+ import { Maybe } from './Maybe';
2
2
  type GetterFn<T> = (x: T) => Maybe<T>;
3
3
  export default GetterFn;
@@ -1 +1 @@
1
- export declare function compareNumber(a: any, b: any): number;
1
+ export declare function compareNumber(a: number, b: number): number;
@@ -8,8 +8,8 @@ export declare function isDateInRange(date: Date, validFrom: Date, validTo: Date
8
8
  export declare const parseDate: (isoString: string) => "" | Date;
9
9
  export declare function formatDatetime(date: Date, formatString?: string, options?: {}): string;
10
10
  export declare function formatDatetimeTZ(date: Date | string | object, formatString?: string, options?: {}, isLocalTime?: boolean): string;
11
- export declare function getDayOfWeek(date: any): string;
12
- export declare function formatDateToMSK(date: any): string;
11
+ export declare function getDayOfWeek(date: Date | number): string;
12
+ export declare function formatDateToMSK(date: Date | string | number): string;
13
13
  export declare function extractTime(date: Date | string | object, isLocalTime?: boolean): string;
14
14
  export declare function findMinMaxDates(dates: Set<Date>): {
15
15
  minDate: Date;
@@ -26,9 +26,9 @@ export declare function toIsoZDate(value: string): string | null;
26
26
  export declare function toIsoZDateTime(value: string): string | null;
27
27
  export declare function isoToDateInput(value: unknown): string;
28
28
  export declare function isoToDateTimeLocalInput(value: unknown): string;
29
- /** Formats a DateTime as `HH:mm` in the configured IANA timezone or browser-local timezone. */
29
+ /** Форматирует DateTime как `HH:mm` в настроенном часовом поясе IANA или локальном поясе браузера. */
30
30
  export declare function isoDateTimeToTimeInput(value: unknown, timezone?: unknown): string;
31
- /** Replaces only hours and minutes while preserving the DateTime calendar date in the selected timezone. */
31
+ /** Заменяет только часы и минуты, сохраняя календарную дату DateTime в выбранном часовом поясе. */
32
32
  export declare function mergeTimeIntoDateTime(value: unknown, time: unknown, timezone?: unknown): string | null;
33
33
  export declare function timeToTimeInput(value: unknown): string;
34
34
  export declare function toTimeHHMMSS(value: unknown): string | null;
@@ -1,4 +1,4 @@
1
- /** Returns a bounded string without traversing or retaining the supplied value. */
1
+ /** Возвращает строку ограниченной длины без обхода или удержания переданного значения. */
2
2
  export declare function consoleValueSummary(value: unknown): string;
3
- /** Returns Error metadata as text without forwarding the Error object to Console. */
3
+ /** Возвращает метаданные Error как текст, не передавая объект Error в Console. */
4
4
  export declare function consoleErrorSummary(error: unknown): string;
@@ -15,7 +15,7 @@ export interface KeyboardStateSnapshot {
15
15
  code: string[];
16
16
  };
17
17
  }
18
- /** Returns the shared document-scoped keyboard snapshot, installing one tracker lazily. */
18
+ /** Возвращает общий snapshot клавиатуры уровня document, лениво устанавливая один tracker. */
19
19
  export declare function getKeyboardStateSnapshot(target: Document): KeyboardStateSnapshot;
20
- /** Subscribes to the shared document-scoped keyboard state and immediately emits its snapshot. */
20
+ /** Подписывается на общее состояние клавиатуры уровня document и сразу публикует его snapshot. */
21
21
  export declare function subscribeKeyboardState(target: Document, listener: (snapshot: KeyboardStateSnapshot) => void): () => void;
@@ -1,4 +1,4 @@
1
- import { ChangeNotifier } from '../events/ChangeNotifier';
1
+ import { Subscribable } from '../events/Subscribable';
2
2
  /**
3
3
  * Структурированная запись лога.
4
4
  *
@@ -30,7 +30,7 @@ export interface StructuredLogEntry {
30
30
  actions?: Array<{
31
31
  icon: string;
32
32
  tooltip?: string;
33
- handler: () => void;
33
+ handler?: () => void;
34
34
  }>;
35
35
  }
36
36
  /**
@@ -61,7 +61,7 @@ export interface StructuredLogEntry {
61
61
  * // Получаем все логи
62
62
  * const logs = logger.getLogs()
63
63
  */
64
- export declare class StructuredLogger extends ChangeNotifier {
64
+ export declare class StructuredLogger extends Subscribable {
65
65
  /** Массив всех логов */
66
66
  private _logs;
67
67
  /** Текущий контекст (иерархия) */
@@ -45,7 +45,7 @@ export type Awaitable<T> = T | Promise<T>;
45
45
  */
46
46
  export type VoidFn = () => void;
47
47
  /**
48
- * Backward-compatible alias used by legacy packages.
48
+ * Alias для обратной совместимости, используемый legacy-пакетами.
49
49
  */
50
50
  export type VoidFunction = VoidFn;
51
51
  /**
@@ -53,7 +53,7 @@ export type VoidFunction = VoidFn;
53
53
  */
54
54
  export type Dictionary<T = any> = Record<string, T>;
55
55
  /**
56
- * Backward-compatible loose object record.
56
+ * Нестрогая запись объекта для обратной совместимости.
57
57
  */
58
58
  export type AnyRecord = Record<string, any>;
59
59
  /**
@@ -18,6 +18,7 @@ export declare class SSEManager {
18
18
  constructor(options: SSEManagerOptions);
19
19
  start(): void;
20
20
  stop(): void;
21
+ private _isCurrent;
21
22
  private _scheduleReconnect;
22
23
  private _clearReconnect;
23
24
  private _buildHeaders;
package/dist/utils.js CHANGED
@@ -1,31 +1,15 @@
1
1
  var V = Object.defineProperty;
2
2
  var G = (r, t, e) => t in r ? V(r, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : r[t] = e;
3
3
  var o = (r, t, e) => G(r, typeof t != "symbol" ? t + "" : t, e);
4
- import { Transform as f, TransformationType as _, plainToInstance as T, instanceToPlain as S, Expose as J } from "class-transformer";
4
+ import { Transform as d, TransformationType as _, plainToInstance as b, instanceToPlain as T, Expose as J } from "class-transformer";
5
5
  import { IsOptional as Z } from "class-validator";
6
6
  import "reflect-metadata";
7
7
  import { v4 as W } from "uuid";
8
8
  import { DateTime as Y } from "ts-luxon";
9
- import { differenceInSeconds as N, format as g, differenceInCalendarDays as q, isAfter as D, isEqual as Q, isBefore as z, startOfDay as p, endOfDay as X } from "date-fns";
10
- import { utcToZonedTime as I, getTimezoneOffset as w, zonedTimeToUtc as v } from "date-fns-tz";
9
+ import { differenceInSeconds as z, format as g, differenceInCalendarDays as q, isAfter as I, isEqual as Q, isBefore as P, startOfDay as p, endOfDay as X } from "date-fns";
10
+ import { utcToZonedTime as E, getTimezoneOffset as w, zonedTimeToUtc as v } from "date-fns-tz";
11
11
  import { fetchEventSource as tt, EventStreamContentType as et } from "@microsoft/fetch-event-source";
12
12
  var m = /* @__PURE__ */ ((r) => (r.Add = "add", r.Remove = "remove", r.Update = "update", r.IndexCreate = "indexCreate", r))(m || {});
13
- class P {
14
- constructor() {
15
- o(this, "_listeners", /* @__PURE__ */ new Set());
16
- }
17
- /** Подписывает listener на изменения utility owner. */
18
- subscribe(t) {
19
- return this._listeners.add(t), () => {
20
- this._listeners.delete(t);
21
- };
22
- }
23
- /** Уведомляет текущих listeners об изменении. */
24
- notify() {
25
- for (const t of this._listeners)
26
- t();
27
- }
28
- }
29
13
  class H {
30
14
  /**
31
15
  * Создает экземпляр EventBus и подготавливает базовое состояние.
@@ -153,7 +137,23 @@ class H {
153
137
  }
154
138
  }
155
139
  const wt = new H(Object.keys({}));
156
- class xt extends P {
140
+ class U {
141
+ constructor() {
142
+ o(this, "_subscribers", /* @__PURE__ */ new Set());
143
+ }
144
+ /** Подписывает listener и возвращает идемпотентную функцию отписки. */
145
+ subscribe(t) {
146
+ return this._subscribers.add(t), () => {
147
+ this._subscribers.delete(t);
148
+ };
149
+ }
150
+ /** Уведомляет текущих подписчиков об изменении владельца состояния. */
151
+ notify() {
152
+ for (const t of this._subscribers)
153
+ t();
154
+ }
155
+ }
156
+ class xt extends U {
157
157
  /**
158
158
  * Создает экземпляр Collection и подготавливает базовое состояние.
159
159
  */
@@ -185,8 +185,8 @@ class xt extends P {
185
185
  const a = typeof s == "string" ? s : s.id, l = this._items.findIndex((u) => u.id === a);
186
186
  if (l !== -1) {
187
187
  const [u] = this._items.splice(l, 1);
188
- this._indices.forEach((c, h) => {
189
- c.delete(u[h]);
188
+ this._indices.forEach((c, f) => {
189
+ c.delete(u[f]);
190
190
  }), u.parentId || this._rootIds.delete(u.id), i.push(u);
191
191
  }
192
192
  }), i.length && (this._bus.emit(m.Remove, i), this.notify());
@@ -591,7 +591,7 @@ class Et {
591
591
  return await n.json().catch(() => ({}));
592
592
  }
593
593
  }
594
- class At {
594
+ class Ct {
595
595
  /**
596
596
  * Создает экземпляр DelayedExecutor и подготавливает базовое состояние.
597
597
  */
@@ -635,10 +635,10 @@ function x(r) {
635
635
  var t;
636
636
  return r == null ? String(r) : typeof r == "string" ? `string(${r.length})` : typeof r != "object" ? `${typeof r}(${String(r)})` : Array.isArray(r) ? `Array(${r.length})` : r instanceof Map ? `Map(${r.size})` : r instanceof Set ? `Set(${r.size})` : ((t = r.constructor) == null ? void 0 : t.name) || "Object";
637
637
  }
638
- function U(r) {
638
+ function D(r) {
639
639
  return r instanceof Error ? `${r.name}: ${r.message}` : x(r);
640
640
  }
641
- class Ot {
641
+ class At {
642
642
  /**
643
643
  * Создает экземпляр NamedExecutor и подготавливает базовое состояние.
644
644
  */
@@ -675,7 +675,7 @@ class Ot {
675
675
  const e = this._callbacks.get(t);
676
676
  e && e();
677
677
  } catch (e) {
678
- console.error(`[NamedExecutor] flush error: ${U(e)}`);
678
+ console.error(`[NamedExecutor] flush error: ${D(e)}`);
679
679
  }
680
680
  this._clear(t);
681
681
  }
@@ -699,9 +699,9 @@ class Ot {
699
699
  clearTimeout(this._delayTimers.get(t)), clearTimeout(this._maxTimers.get(t)), this._delayTimers.delete(t), this._maxTimers.delete(t), this._callbacks.delete(t), this._firstCallTime.delete(t);
700
700
  }
701
701
  }
702
- function Ct() {
702
+ function Ot() {
703
703
  return function(r, t) {
704
- f(
704
+ d(
705
705
  ({ value: e }) => {
706
706
  if (typeof e == "string")
707
707
  try {
@@ -712,7 +712,7 @@ function Ct() {
712
712
  return e;
713
713
  },
714
714
  { toClassOnly: !0 }
715
- )(r, t), f(
715
+ )(r, t), d(
716
716
  ({ value: e }) => {
717
717
  try {
718
718
  return JSON.stringify(e);
@@ -726,7 +726,7 @@ function Ct() {
726
726
  }
727
727
  function Mt() {
728
728
  return function(r, t) {
729
- f(
729
+ d(
730
730
  ({ value: e }) => {
731
731
  if (e == null)
732
732
  return "{}";
@@ -739,7 +739,7 @@ function Mt() {
739
739
  return e;
740
740
  },
741
741
  { toClassOnly: !0 }
742
- )(r, t), f(
742
+ )(r, t), d(
743
743
  ({ value: e }) => {
744
744
  if (!e)
745
745
  return {};
@@ -755,39 +755,39 @@ function Mt() {
755
755
  )(r, t);
756
756
  };
757
757
  }
758
- const R = Symbol("onDeserialized");
758
+ const K = Symbol("onDeserialized");
759
759
  function $t() {
760
760
  return function(r, t) {
761
- Reflect.defineMetadata(R, t, r);
761
+ Reflect.defineMetadata(K, t, r);
762
762
  };
763
763
  }
764
764
  function rt(r) {
765
765
  const t = Reflect.getMetadata(
766
- R,
766
+ K,
767
767
  r
768
768
  );
769
769
  return t ? r[t].bind(r) : null;
770
770
  }
771
- function Ft() {
771
+ function kt() {
772
772
  return function(r, t) {
773
- f(
773
+ d(
774
774
  ({ value: e }) => typeof e == "string" ? e.trim() : String(e ?? ""),
775
775
  { toClassOnly: !0 }
776
- )(r, t), f(
776
+ )(r, t), d(
777
777
  ({ value: e }) => typeof e == "string" ? e : String(e ?? ""),
778
778
  { toPlainOnly: !0 }
779
779
  )(r, t);
780
780
  };
781
781
  }
782
- function kt(r, t) {
783
- return f(({ value: e, type: n }) => {
782
+ function Ft(r, t) {
783
+ return d(({ value: e, type: n }) => {
784
784
  if (!e)
785
785
  return /* @__PURE__ */ new Map();
786
786
  if (n === _.PLAIN_TO_CLASS) {
787
787
  if (Array.isArray(e))
788
788
  return t ? new Map(
789
789
  e.map((i) => {
790
- const s = T(r, i);
790
+ const s = b(r, i);
791
791
  return [s[t], s];
792
792
  })
793
793
  ) : (console.warn(
@@ -804,23 +804,23 @@ function kt(r, t) {
804
804
  }
805
805
  return console.warn(`[TypeMap] Expected object or array, got ${x(e)}`), /* @__PURE__ */ new Map();
806
806
  }
807
- return n === _.CLASS_TO_PLAIN ? e instanceof Map ? Array.from(e.values()).map((i) => S(i)) : (console.warn(`[TypeMap] Expected Map, got ${x(e)}`), t ? [] : {}) : (console.warn(`[TypeMap] Unexpected transformation type: ${String(n)}`), e);
807
+ return n === _.CLASS_TO_PLAIN ? e instanceof Map ? Array.from(e.values()).map((i) => T(i)) : (console.warn(`[TypeMap] Expected Map, got ${x(e)}`), t ? [] : {}) : (console.warn(`[TypeMap] Unexpected transformation type: ${String(n)}`), e);
808
808
  });
809
809
  }
810
810
  function Lt(r) {
811
- return f(({ value: t, type: e }) => {
811
+ return d(({ value: t, type: e }) => {
812
812
  if (!t || typeof t != "object")
813
813
  return {};
814
814
  if (e === _.PLAIN_TO_CLASS) {
815
815
  const n = {};
816
816
  for (const i of Object.keys(t))
817
- n[i] = T(r, t[i]);
817
+ n[i] = b(r, t[i]);
818
818
  return n;
819
819
  }
820
820
  if (e === _.CLASS_TO_PLAIN) {
821
821
  const n = {};
822
822
  for (const i of Object.keys(t))
823
- n[i] = S(t[i]);
823
+ n[i] = T(t[i]);
824
824
  return n;
825
825
  }
826
826
  return t;
@@ -831,7 +831,7 @@ class Nt {
831
831
  * Выполняет действие toPlain в рамках ответственности Serialize.
832
832
  */
833
833
  static toPlain(t) {
834
- return S(t, {
834
+ return T(t, {
835
835
  exposeDefaultValues: !0,
836
836
  excludeExtraneousValues: !0
837
837
  });
@@ -840,7 +840,7 @@ class Nt {
840
840
  * Выполняет действие fromJSON в рамках ответственности Serialize.
841
841
  */
842
842
  static fromJSON(t, e) {
843
- const n = T(t, e, {
843
+ const n = b(t, e, {
844
844
  exposeDefaultValues: !0,
845
845
  excludeExtraneousValues: !0
846
846
  }), i = rt(n);
@@ -863,32 +863,32 @@ function Ht(r, t, e) {
863
863
  }
864
864
  function Ut(r) {
865
865
  return function(t, e) {
866
- f(({ value: n }) => n === null ? void 0 : n, { toPlainOnly: !0 })(t, e), Z(r)(t, e);
866
+ d(({ value: n }) => n === null ? void 0 : n, { toPlainOnly: !0 })(t, e), Z(r)(t, e);
867
867
  };
868
868
  }
869
- function Rt() {
870
- return f(({ value: r, type: t }) => t === _.PLAIN_TO_CLASS ? r == null ? void 0 : r.id : r);
869
+ function Kt() {
870
+ return d(({ value: r, type: t }) => t === _.PLAIN_TO_CLASS ? r == null ? void 0 : r.id : r);
871
871
  }
872
- function Kt(r) {
873
- return f(({ value: t, type: e }) => e === _.PLAIN_TO_CLASS ? t == null ? void 0 : t.map((n) => n == null ? void 0 : n[r]) : t);
872
+ function Rt(r) {
873
+ return d(({ value: t, type: e }) => e === _.PLAIN_TO_CLASS ? t == null ? void 0 : t.map((n) => n == null ? void 0 : n[r]) : t);
874
874
  }
875
875
  function jt() {
876
- return f(({ value: r, type: t }) => t === _.CLASS_TO_PLAIN && (r == null ? void 0 : r.id) || r);
876
+ return d(({ value: r, type: t }) => t === _.CLASS_TO_PLAIN && (r == null ? void 0 : r.id) || r);
877
877
  }
878
878
  function Bt() {
879
- return f(({ value: r, type: t }) => t === _.CLASS_TO_PLAIN ? r.map((e) => e.id) : r);
879
+ return d(({ value: r, type: t }) => t === _.CLASS_TO_PLAIN ? r.map((e) => e.id) : r);
880
880
  }
881
881
  function Vt() {
882
- return f(({ value: r, type: t }) => t === "classToPlain" ? void 0 : r, { toPlainOnly: !0 });
882
+ return d(({ value: r, type: t }) => t === _.CLASS_TO_PLAIN ? void 0 : r, { toPlainOnly: !0 });
883
883
  }
884
884
  function Gt(r, t) {
885
- return T(r, t, {
885
+ return b(r, t, {
886
886
  exposeDefaultValues: !0,
887
887
  excludeExtraneousValues: !0
888
888
  });
889
889
  }
890
890
  function Jt(r) {
891
- return S(r, {
891
+ return T(r, {
892
892
  exposeUnsetFields: !1
893
893
  });
894
894
  }
@@ -902,11 +902,11 @@ const Yt = !1;
902
902
  function qt(r, t) {
903
903
  return t();
904
904
  }
905
- const Qt = () => W(), M = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
905
+ const Qt = () => W(), $ = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
906
906
  function Xt(r) {
907
907
  let t = "";
908
908
  for (let e = 0; e < r; ++e)
909
- t += M[Math.floor(M.length * Math.random())];
909
+ t += $[Math.floor($.length * Math.random())];
910
910
  return t;
911
911
  }
912
912
  class vt {
@@ -938,7 +938,7 @@ class vt {
938
938
  * Обрабатывает runtime-событие HotkeyManager.
939
939
  */
940
940
  _handle(t) {
941
- if (!this._enabled || this._isIgnoredTarget(t.target))
941
+ if (!(t instanceof KeyboardEvent) || !this._enabled || this._isIgnoredTarget(t.target))
942
942
  return;
943
943
  const e = this._normalizeKey(t), n = this._bindings.get(e);
944
944
  if (n)
@@ -998,7 +998,7 @@ function te(r, t) {
998
998
  return n && i && s && a && l;
999
999
  }) : !1;
1000
1000
  }
1001
- const $ = /* @__PURE__ */ new WeakMap(), it = /* @__PURE__ */ new Set([
1001
+ const k = /* @__PURE__ */ new WeakMap(), it = /* @__PURE__ */ new Set([
1002
1002
  "Alt",
1003
1003
  "AltGraph",
1004
1004
  "CapsLock",
@@ -1016,15 +1016,15 @@ const $ = /* @__PURE__ */ new WeakMap(), it = /* @__PURE__ */ new Set([
1016
1016
  "SymbolLock"
1017
1017
  ]);
1018
1018
  function ee(r) {
1019
- return E(K(r).snapshot);
1019
+ return C(R(r).snapshot);
1020
1020
  }
1021
1021
  function re(r, t) {
1022
- const e = K(r);
1023
- return e.subscribers.add(t), t(E(e.snapshot)), () => e.subscribers.delete(t);
1022
+ const e = R(r);
1023
+ return e.subscribers.add(t), t(C(e.snapshot)), () => e.subscribers.delete(t);
1024
1024
  }
1025
- function K(r) {
1025
+ function R(r) {
1026
1026
  var a, l, u;
1027
- const t = $.get(r);
1027
+ const t = k.get(r);
1028
1028
  if (t)
1029
1029
  return t;
1030
1030
  const e = st((a = r.defaultView) == null ? void 0 : a.navigator), n = {
@@ -1032,42 +1032,42 @@ function K(r) {
1032
1032
  entries: /* @__PURE__ */ new Map(),
1033
1033
  subscribers: /* @__PURE__ */ new Set()
1034
1034
  }, i = (c) => {
1035
- var C;
1036
- const h = c ? {
1035
+ var M;
1036
+ const f = c ? {
1037
1037
  ctrl: c.ctrlKey,
1038
1038
  shift: c.shiftKey,
1039
1039
  alt: c.altKey,
1040
1040
  meta: c.metaKey,
1041
1041
  mod: e === "macos" ? c.metaKey : e === "windows" || e === "linux" ? c.ctrlKey : c.ctrlKey || c.metaKey,
1042
- altGraph: ((C = c.getModifierState) == null ? void 0 : C.call(c, "AltGraph")) === !0
1043
- } : F(e).modifiers, O = [...n.entries.values()], b = {
1042
+ altGraph: ((M = c.getModifierState) == null ? void 0 : M.call(c, "AltGraph")) === !0
1043
+ } : F(e).modifiers, O = [...n.entries.values()], S = {
1044
1044
  platform: e,
1045
- modifiers: h,
1045
+ modifiers: f,
1046
1046
  held: {
1047
1047
  key: [...new Set(O.map((y) => y.key))].sort(),
1048
1048
  code: [...new Set(O.map((y) => y.code).filter(Boolean))].sort()
1049
1049
  }
1050
1050
  };
1051
- if (!ot(n.snapshot, b)) {
1052
- n.snapshot = b;
1051
+ if (!ot(n.snapshot, S)) {
1052
+ n.snapshot = S;
1053
1053
  for (const y of n.subscribers)
1054
- y(E(b));
1054
+ y(C(S));
1055
1055
  }
1056
1056
  }, s = () => {
1057
1057
  n.entries.clear(), i();
1058
1058
  };
1059
1059
  return r.addEventListener("keydown", (c) => {
1060
1060
  if (!it.has(c.key)) {
1061
- const h = c.key.toLowerCase();
1062
- n.entries.set(c.code || `key:${h}`, { key: h, code: c.code });
1061
+ const f = c.key.toLowerCase();
1062
+ n.entries.set(c.code || `key:${f}`, { key: f, code: c.code });
1063
1063
  }
1064
1064
  i(c);
1065
1065
  }, !0), r.addEventListener("keyup", (c) => {
1066
- const h = c.key.toLowerCase();
1067
- n.entries.delete(c.code || `key:${h}`), i(c);
1066
+ const f = c.key.toLowerCase();
1067
+ n.entries.delete(c.code || `key:${f}`), i(c);
1068
1068
  }, !0), r.addEventListener("visibilitychange", () => {
1069
1069
  r.visibilityState === "hidden" && s();
1070
- }), (l = r.defaultView) == null || l.addEventListener("blur", s), (u = r.defaultView) == null || u.addEventListener("pagehide", s), $.set(r, n), n;
1070
+ }), (l = r.defaultView) == null || l.addEventListener("blur", s), (u = r.defaultView) == null || u.addEventListener("pagehide", s), k.set(r, n), n;
1071
1071
  }
1072
1072
  function F(r) {
1073
1073
  return {
@@ -1089,19 +1089,19 @@ function st(r) {
1089
1089
  return e.includes("mac") || e.includes("darwin") || e.includes("iphone") || e.includes("ipad") ? "macos" : e.includes("win") ? "windows" : e.includes("linux") || e.includes("x11") || e.includes("cros") ? "linux" : "unknown";
1090
1090
  }
1091
1091
  function ot(r, t) {
1092
- return r.platform === t.platform && r.modifiers.ctrl === t.modifiers.ctrl && r.modifiers.shift === t.modifiers.shift && r.modifiers.alt === t.modifiers.alt && r.modifiers.meta === t.modifiers.meta && r.modifiers.mod === t.modifiers.mod && r.modifiers.altGraph === t.modifiers.altGraph && k(r.held.key, t.held.key) && k(r.held.code, t.held.code);
1092
+ return r.platform === t.platform && r.modifiers.ctrl === t.modifiers.ctrl && r.modifiers.shift === t.modifiers.shift && r.modifiers.alt === t.modifiers.alt && r.modifiers.meta === t.modifiers.meta && r.modifiers.mod === t.modifiers.mod && r.modifiers.altGraph === t.modifiers.altGraph && L(r.held.key, t.held.key) && L(r.held.code, t.held.code);
1093
1093
  }
1094
- function k(r, t) {
1094
+ function L(r, t) {
1095
1095
  return r.length === t.length && r.every((e, n) => e === t[n]);
1096
1096
  }
1097
- function E(r) {
1097
+ function C(r) {
1098
1098
  return {
1099
1099
  platform: r.platform,
1100
1100
  modifiers: { ...r.modifiers },
1101
1101
  held: { key: [...r.held.key], code: [...r.held.code] }
1102
1102
  };
1103
1103
  }
1104
- class ne extends P {
1104
+ class ne extends U {
1105
1105
  constructor() {
1106
1106
  super(...arguments);
1107
1107
  /** Массив всех логов */
@@ -1145,7 +1145,7 @@ class ne extends P {
1145
1145
  */
1146
1146
  end(e, n, i) {
1147
1147
  if (n) {
1148
- const s = i ?? this._currentActions.length ? this._currentActions : void 0;
1148
+ const s = i != null && i.length ? i : this._currentActions.length > 0 ? this._currentActions : void 0;
1149
1149
  this._log(e ?? "info", n, s);
1150
1150
  }
1151
1151
  return this._currentContext.pop(), this._currentActions = [], this;
@@ -1305,14 +1305,14 @@ function ae(r) {
1305
1305
  return String(r).charAt(0).toUpperCase() + String(r).slice(1);
1306
1306
  }
1307
1307
  function ce(r, t) {
1308
- return D(r, t) || Q(r, t);
1308
+ return I(r, t) || Q(r, t);
1309
1309
  }
1310
1310
  function le(r, t, e, n) {
1311
1311
  const i = p(r), s = p(t), a = p(e), l = p(n);
1312
- return !z(s, a) && !D(i, l);
1312
+ return !P(s, a) && !I(i, l);
1313
1313
  }
1314
1314
  function ue(r, t, e) {
1315
- return !z(r, p(t)) && !D(r, X(e));
1315
+ return !P(r, p(t)) && !I(r, X(e));
1316
1316
  }
1317
1317
  const fe = (r) => r && new Date(r);
1318
1318
  function de(r, t = "HH:mm dd.MM.yyyy", e = {}) {
@@ -1328,7 +1328,7 @@ function ut(r, t = "HH:mm dd.MM.yyyy", e = {}, n = !0) {
1328
1328
  return "";
1329
1329
  } else
1330
1330
  r = new Date(r.toString());
1331
- return n ? g(r, t, e) : g(I(r, "utc"), t, e);
1331
+ return n ? g(r, t, e) : g(E(r, "utc"), t, e);
1332
1332
  }
1333
1333
  function he(r) {
1334
1334
  const t = { weekday: "short" }, e = new Intl.DateTimeFormat("ru-RU", t).format(r);
@@ -1349,18 +1349,18 @@ function ye(r) {
1349
1349
  };
1350
1350
  }
1351
1351
  function pe(r, t) {
1352
- const e = N(r, t), { hours: n, minutes: i } = A(e);
1353
- return n || i ? `${e > 0 ? "-" : "+"}${d(n)}:${d(i)}` : "";
1352
+ const e = z(r, t), { hours: n, minutes: i } = A(e);
1353
+ return n || i ? `${e > 0 ? "-" : "+"}${h(n)}:${h(i)}` : "";
1354
1354
  }
1355
1355
  function ge(r, t) {
1356
- const e = N(r, t), { hours: n, minutes: i } = A(e);
1357
- return n || i ? `${e > 0 ? "-" : ""}${d(n)}:${d(i)}` : "";
1356
+ const e = z(r, t), { hours: n, minutes: i } = A(e);
1357
+ return n || i ? `${e > 0 ? "-" : ""}${h(n)}:${h(i)}` : "";
1358
1358
  }
1359
- function L(r = /* @__PURE__ */ new Date()) {
1359
+ function N(r = /* @__PURE__ */ new Date()) {
1360
1360
  return new Date(r.getFullYear(), r.getMonth(), r.getDate());
1361
1361
  }
1362
- function Te(r, t) {
1363
- const e = q(L(r), L(t));
1362
+ function be(r, t) {
1363
+ const e = q(N(r), N(t));
1364
1364
  return e ? e > 7 ? {
1365
1365
  variant: "red",
1366
1366
  value: ">7"
@@ -1375,21 +1375,21 @@ function Te(r, t) {
1375
1375
  value: `${e}`
1376
1376
  } : null;
1377
1377
  }
1378
- function Se(r) {
1378
+ function Te(r) {
1379
1379
  const e = String(r ?? "").trim().match(/^(\d{4})-(\d{2})-(\d{2})$/);
1380
1380
  if (!e)
1381
1381
  return null;
1382
1382
  const n = Number(e[1]), i = Number(e[2]) - 1, s = Number(e[3]), a = new Date(Date.UTC(n, i, s, 0, 0, 0, 0));
1383
1383
  return Number.isNaN(a.getTime()) ? null : a.toISOString();
1384
1384
  }
1385
- function be(r) {
1385
+ function Se(r) {
1386
1386
  const t = String(r ?? "").trim();
1387
1387
  if (!t)
1388
1388
  return null;
1389
1389
  const e = t.match(/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2})(?::(\d{2}))?$/);
1390
1390
  if (e) {
1391
- const i = Number(e[1]), s = Number(e[2]) - 1, a = Number(e[3]), l = Number(e[4]), u = Number(e[5]), c = e[6] != null ? Number(e[6]) : 0, h = new Date(i, s, a, l, u, c, 0);
1392
- return Number.isNaN(h.getTime()) ? null : h.toISOString();
1391
+ const i = Number(e[1]), s = Number(e[2]) - 1, a = Number(e[3]), l = Number(e[4]), u = Number(e[5]), c = e[6] != null ? Number(e[6]) : 0, f = new Date(i, s, a, l, u, c, 0);
1392
+ return Number.isNaN(f.getTime()) ? null : f.toISOString();
1393
1393
  }
1394
1394
  const n = new Date(t);
1395
1395
  return Number.isNaN(n.getTime()) ? null : n.toISOString();
@@ -1405,7 +1405,7 @@ function xe(r) {
1405
1405
  const e = new Date(t);
1406
1406
  if (Number.isNaN(e.getTime()))
1407
1407
  return t.slice(0, 16);
1408
- const n = e.getFullYear(), i = d(e.getMonth() + 1), s = d(e.getDate()), a = d(e.getHours()), l = d(e.getMinutes());
1408
+ const n = e.getFullYear(), i = h(e.getMonth() + 1), s = h(e.getDate()), a = h(e.getHours()), l = h(e.getMinutes());
1409
1409
  return `${n}-${i}-${s}T${a}:${l}`;
1410
1410
  }
1411
1411
  function De(r, t) {
@@ -1415,8 +1415,8 @@ function De(r, t) {
1415
1415
  const n = new Date(String(r ?? "").trim());
1416
1416
  if (Number.isNaN(n.getTime()))
1417
1417
  return "";
1418
- const i = B(t), s = i ? I(n, i) : n;
1419
- return `${d(s.getHours())}:${d(s.getMinutes())}`;
1418
+ const i = B(t), s = i ? E(n, i) : n;
1419
+ return `${h(s.getHours())}:${h(s.getMinutes())}`;
1420
1420
  }
1421
1421
  function Ie(r, t, e) {
1422
1422
  const n = j(t).match(/^(\d{2}):(\d{2})$/);
@@ -1431,7 +1431,7 @@ function Ie(r, t, e) {
1431
1431
  const l = B(e);
1432
1432
  if (!l)
1433
1433
  return i.setHours(s, a, 0, 0), i.toISOString();
1434
- const u = I(i, l);
1434
+ const u = E(i, l);
1435
1435
  return u.setHours(s, a, 0, 0), v(u, l).toISOString();
1436
1436
  }
1437
1437
  function j(r) {
@@ -1468,11 +1468,11 @@ function Ee(r) {
1468
1468
  const n = t.match(/^(\d{2}):(\d{2})$/);
1469
1469
  return n ? `${n[1]}:${n[2]}:00` : null;
1470
1470
  }
1471
- function Ae(r) {
1471
+ function Ce(r) {
1472
1472
  const t = dt(r), e = Math.sign(t) >= 0 ? "" : "-", { hours: n, minutes: i } = A(t);
1473
- return `${e}${d(n)}:${d(i)}`;
1473
+ return `${e}${h(n)}:${h(i)}`;
1474
1474
  }
1475
- function Oe(r = null, t = "dd", e = {}) {
1475
+ function Ae(r = null, t = "dd", e = {}) {
1476
1476
  const n = ft(r);
1477
1477
  if (!n)
1478
1478
  return "";
@@ -1506,10 +1506,10 @@ function dt(r) {
1506
1506
  }
1507
1507
  return 0;
1508
1508
  }
1509
- function d(r) {
1509
+ function h(r) {
1510
1510
  return String(r).padStart(2, "0");
1511
1511
  }
1512
- function Ce(r) {
1512
+ function Oe(r) {
1513
1513
  const t = /* @__PURE__ */ new Date();
1514
1514
  try {
1515
1515
  const e = w(r, t), n = Intl.supportedValuesOf("timeZone");
@@ -1535,14 +1535,23 @@ class $e {
1535
1535
  this._url = t.url, this._retryInterval = t.retryInterval ?? 3e3, this._options = t;
1536
1536
  }
1537
1537
  start() {
1538
- this._abortController = new AbortController(), this._connect();
1538
+ if (this._abortController)
1539
+ return;
1540
+ const t = new AbortController();
1541
+ this._abortController = t, this._connect(t);
1539
1542
  }
1540
1543
  stop() {
1541
- var t;
1542
- this._clearReconnect(), this._isConnected = !1, (t = this._abortController) == null || t.abort(), this._abortController = null;
1544
+ this._clearReconnect(), this._isConnected = !1;
1545
+ const t = this._abortController;
1546
+ this._abortController = null, t == null || t.abort();
1547
+ }
1548
+ _isCurrent(t) {
1549
+ return this._abortController === t && !t.signal.aborted;
1543
1550
  }
1544
- _scheduleReconnect() {
1545
- this._clearReconnect(), this._reconnectTimeout = setTimeout(() => this.start(), this._retryInterval);
1551
+ _scheduleReconnect(t) {
1552
+ this._isCurrent(t) && (this._clearReconnect(), this._reconnectTimeout = setTimeout(() => {
1553
+ this._isCurrent(t) && (this.stop(), this.start());
1554
+ }, this._retryInterval));
1546
1555
  }
1547
1556
  _clearReconnect() {
1548
1557
  this._reconnectTimeout && (clearTimeout(this._reconnectTimeout), this._reconnectTimeout = null);
@@ -1552,48 +1561,62 @@ class $e {
1552
1561
  const t = { ...this._options.headers }, e = await ((i = (n = this._options).getToken) == null ? void 0 : i.call(n));
1553
1562
  return e && (t.Authorization = `Bearer ${e}`), t;
1554
1563
  }
1555
- async _connect() {
1556
- var t, e, n;
1564
+ async _connect(t) {
1565
+ var e, n;
1557
1566
  try {
1567
+ const i = await this._buildHeaders();
1568
+ if (!this._isCurrent(t))
1569
+ return;
1558
1570
  await tt(this._url, {
1559
1571
  method: "GET",
1560
- headers: await this._buildHeaders(),
1561
- signal: (t = this._abortController) == null ? void 0 : t.signal,
1572
+ headers: i,
1573
+ signal: t.signal,
1562
1574
  openWhenHidden: !0,
1563
- onopen: (i) => {
1564
- var a, l;
1565
- if (i.ok && i.headers.get("content-type") === et) {
1566
- this._isConnected = !0, (l = (a = this._options).onOpen) == null || l.call(a);
1575
+ onopen: async (s) => {
1576
+ var l, u, c, f;
1577
+ if (!this._isCurrent(t))
1578
+ throw new Error("[SSEManager] Connection was stopped.");
1579
+ if (s.ok && ((u = (l = s.headers.get("content-type")) == null ? void 0 : l.split(";")[0]) == null ? void 0 : u.trim()) === et) {
1580
+ this._isConnected = !0, (f = (c = this._options).onOpen) == null || f.call(c);
1567
1581
  return;
1568
1582
  }
1569
- throw new Error(`Unexpected response: ${i.status}`);
1583
+ throw new Error(`Unexpected response: ${s.status}`);
1570
1584
  },
1571
- onmessage: (i) => {
1572
- try {
1573
- this._options.onEvent(JSON.parse(i.data));
1574
- } catch (s) {
1575
- console.warn(`[SSEManager] Failed to parse message: ${U(s)}`);
1576
- }
1585
+ onmessage: (s) => {
1586
+ if (this._isCurrent(t))
1587
+ try {
1588
+ this._options.onEvent(JSON.parse(s.data));
1589
+ } catch (a) {
1590
+ console.warn(`[SSEManager] Failed to parse message: ${D(a)}`);
1591
+ }
1577
1592
  },
1578
1593
  onclose: () => {
1579
- var i, s;
1580
- this._isConnected = !1, (s = (i = this._options).onClose) == null || s.call(i), this._scheduleReconnect();
1581
- },
1582
- onerror: (i) => {
1583
1594
  var s, a;
1584
- this._isConnected = !1, (a = (s = this._options).onError) == null || a.call(s, i instanceof Error ? i : new Error(String(i))), this._scheduleReconnect();
1595
+ this._isCurrent(t) && (this._isConnected = !1, (a = (s = this._options).onClose) == null || a.call(s));
1596
+ },
1597
+ // Retry belongs to this manager. Throwing disables the library's retry loop.
1598
+ onerror: (s) => {
1599
+ throw s;
1585
1600
  }
1586
1601
  });
1587
1602
  } catch (i) {
1588
- const s = i instanceof Error ? i : new Error(String(i));
1589
- console.error("[SSEManager] Fatal error:", s.message), this._isConnected = !1, (n = (e = this._options).onError) == null || n.call(e, s), this._scheduleReconnect();
1603
+ if (this._isCurrent(t)) {
1604
+ this._isConnected = !1;
1605
+ try {
1606
+ (n = (e = this._options).onError) == null || n.call(e, i instanceof Error ? i : new Error(String(i)));
1607
+ } catch (s) {
1608
+ console.warn(`[SSEManager] Error callback failed: ${D(s)}`);
1609
+ }
1610
+ }
1611
+ } finally {
1612
+ this._isCurrent(t) && (this._isConnected = !1, this._scheduleReconnect(t));
1590
1613
  }
1591
1614
  }
1592
1615
  get isConnected() {
1593
1616
  return this._isConnected;
1594
1617
  }
1595
1618
  }
1596
- class Fe {
1619
+ class ke {
1597
1620
  constructor() {
1598
1621
  o(this, "_currentCount", 0);
1599
1622
  o(this, "_lastResetTime", Date.now());
@@ -1615,9 +1638,9 @@ export {
1615
1638
  wt as AppBus,
1616
1639
  Pt as BeforeSerialize,
1617
1640
  xt as Collection,
1618
- At as DelayedExecutor,
1619
- Kt as DeserializeArrayField,
1620
- Rt as DeserializeId,
1641
+ Ct as DelayedExecutor,
1642
+ Rt as DeserializeArrayField,
1643
+ Kt as DeserializeId,
1621
1644
  H as EventBus,
1622
1645
  m as Events,
1623
1646
  zt as GenericExpose,
@@ -1626,24 +1649,25 @@ export {
1626
1649
  Vt as IgnoreToPlain,
1627
1650
  Dt as IndexedCollection,
1628
1651
  Ut as IsOptionalTransformed,
1629
- Ct as Json,
1652
+ Ot as Json,
1630
1653
  Mt as JsonString,
1631
- Ot as NamedExecutor,
1654
+ At as NamedExecutor,
1632
1655
  Et as PayloadHttpClient,
1633
1656
  It as RingBuffer,
1634
1657
  $e as SSEManager,
1635
- Ft as Script,
1658
+ kt as Script,
1636
1659
  Nt as Serialize,
1637
1660
  jt as SerializeId,
1638
1661
  Bt as SerializeIds,
1639
1662
  ne as StructuredLogger,
1663
+ U as Subscribable,
1640
1664
  lt as SystemClock,
1641
- kt as TypeMap,
1665
+ Ft as TypeMap,
1642
1666
  Lt as TypeRecord,
1643
- Fe as UPSMeter_Service,
1667
+ ke as UPSMeter_Service,
1644
1668
  ae as capitalize,
1645
1669
  Wt as compareNumber,
1646
- U as consoleErrorSummary,
1670
+ D as consoleErrorSummary,
1647
1671
  x as consoleValueSummary,
1648
1672
  ie as createInstance,
1649
1673
  pe as diffDuration,
@@ -1654,9 +1678,9 @@ export {
1654
1678
  _e as formatDateToMSK,
1655
1679
  de as formatDatetime,
1656
1680
  ut as formatDatetimeTZ,
1657
- Oe as formatDatetimeTZSpecial,
1681
+ Ae as formatDatetimeTZSpecial,
1658
1682
  Qt as generateUUID,
1659
- Te as getDateOnlyDiffFactor,
1683
+ be as getDateOnlyDiffFactor,
1660
1684
  he as getDayOfWeek,
1661
1685
  ee as getKeyboardStateSnapshot,
1662
1686
  rt as getOnDeserializedMethod,
@@ -1674,16 +1698,16 @@ export {
1674
1698
  Ie as mergeTimeIntoDateTime,
1675
1699
  $t as onDeserialized,
1676
1700
  fe as parseDate,
1677
- Ae as parseDuration,
1678
- Ce as parseOffsetToTimezone,
1701
+ Ce as parseDuration,
1702
+ Oe as parseOffsetToTimezone,
1679
1703
  qt as profile,
1680
1704
  Xt as randomString,
1681
- L as removeTime,
1705
+ N as removeTime,
1682
1706
  re as subscribeKeyboardState,
1683
1707
  j as timeToTimeInput,
1684
1708
  Gt as toInstance,
1685
- Se as toIsoZDate,
1686
- be as toIsoZDateTime,
1709
+ Te as toIsoZDate,
1710
+ Se as toIsoZDateTime,
1687
1711
  Jt as toPlain,
1688
1712
  Ee as toTimeHHMMSS
1689
1713
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@endge/utils",
3
3
  "type": "module",
4
- "version": "0.25.6",
4
+ "version": "0.26.1",
5
5
  "private": false,
6
6
  "sideEffects": false,
7
7
  "exports": {
@@ -18,7 +18,8 @@
18
18
  "scripts": {
19
19
  "clean": "rimraf dist tsconfig.tsbuildinfo",
20
20
  "dev": "vite build --watch",
21
- "build": "vite build",
21
+ "build": "pnpm typecheck && vite build",
22
+ "typecheck": "tsc -p tsconfig.app.json --noEmit",
22
23
  "test": "vitest",
23
24
  "lint-check": "eslint . --cache",
24
25
  "lint-fix": "eslint . --fix --cache"
@@ -1,8 +0,0 @@
1
- /** Внутренний механизм уведомления generic utilities об изменениях. */
2
- export declare class ChangeNotifier {
3
- private readonly _listeners;
4
- /** Подписывает listener на изменения utility owner. */
5
- subscribe(listener: () => void): () => void;
6
- /** Уведомляет текущих listeners об изменении. */
7
- notify(): void;
8
- }
File without changes