@endge/utils 0.26.0 → 0.27.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.
@@ -5,6 +5,10 @@ import { OneOrMany } from '../tools/tools.types';
5
5
  */
6
6
  export type EventCallback<T = any> = (payload: T) => void;
7
7
  export type EventList = Record<string, any>;
8
+ export interface EventBusOptions {
9
+ /** При наличии изолирует ошибки подписчиков, включая rejected Promise. */
10
+ onListenerError?: (error: unknown, event: string) => void;
11
+ }
8
12
  /**
9
13
  * EventBus реализует паттерн подписки на события.
10
14
  *
@@ -36,11 +40,12 @@ export type EventList = Record<string, any>;
36
40
  * ```
37
41
  */
38
42
  export declare class EventBus<StaticEvents extends Record<string, any>, CustomEventMap extends Record<string, any> = Record<string, any>> {
43
+ private readonly _options;
39
44
  private _listeners;
40
45
  /**
41
46
  * Создает экземпляр EventBus и подготавливает базовое состояние.
42
47
  */
43
- constructor(predefinedEvents?: Array<keyof StaticEvents>);
48
+ constructor(predefinedEvents?: Array<keyof StaticEvents>, _options?: EventBusOptions);
44
49
  /**
45
50
  * Обрабатывает входящее событие EventBus.
46
51
  */
@@ -93,6 +98,7 @@ export declare class EventBus<StaticEvents extends Record<string, any>, CustomEv
93
98
  * Публикует событие во внутренний event bus EventBus.
94
99
  */
95
100
  private _emit;
101
+ private _reportListenerError;
96
102
  /**
97
103
  * Выполняет действие hasListeners в рамках ответственности EventBus.
98
104
  */
@@ -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,23 +1,23 @@
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 b, instanceToPlain as T, Expose as J } from "class-transformer";
4
+ import { Transform as h, 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 x, zonedTimeToUtc as v } from "date-fns-tz";
9
+ import { differenceInSeconds as z, format as g, differenceInCalendarDays as q, isAfter as D, isEqual as Q, isBefore as P, startOfDay as p, endOfDay as X } from "date-fns";
10
+ import { utcToZonedTime as I, 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 {
13
+ class H {
14
14
  /**
15
15
  * Создает экземпляр EventBus и подготавливает базовое состояние.
16
16
  */
17
- constructor(t = []) {
17
+ constructor(t = [], e = {}) {
18
18
  o(this, "_listeners", /* @__PURE__ */ new Map());
19
- t.forEach((e) => {
20
- this._listeners.set(e, /* @__PURE__ */ new Set());
19
+ this._options = e, t.forEach((n) => {
20
+ this._listeners.set(n, /* @__PURE__ */ new Set());
21
21
  });
22
22
  }
23
23
  // ---- Типизированные события ----
@@ -43,8 +43,7 @@ class P {
43
43
  * Выполняет действие offAll в рамках ответственности EventBus.
44
44
  */
45
45
  offAll() {
46
- for (const t of this._listeners.values())
47
- t.clear();
46
+ this._listeners.clear();
48
47
  }
49
48
  /**
50
49
  * Публикует событие во внутренний event bus EventBus.
@@ -101,10 +100,11 @@ class P {
101
100
  * Выполняет внутренний шаг _off для EventBus.
102
101
  */
103
102
  _off(t, e) {
104
- var i;
105
103
  const n = Array.isArray(t) ? t : [t];
106
- for (const s of n)
107
- (i = this._listeners.get(s)) == null || i.delete(e);
104
+ for (const i of n) {
105
+ const s = this._listeners.get(i);
106
+ s == null || s.delete(e), (s == null ? void 0 : s.size) === 0 && this._listeners.delete(i);
107
+ }
108
108
  }
109
109
  /**
110
110
  * Публикует событие во внутренний event bus EventBus.
@@ -112,8 +112,25 @@ class P {
112
112
  _emit(t, e) {
113
113
  const n = this._listeners.get(t);
114
114
  if (n)
115
- for (const i of n)
116
- i(e);
115
+ for (const i of [...n]) {
116
+ if (!this._options.onListenerError) {
117
+ i(e);
118
+ continue;
119
+ }
120
+ try {
121
+ const s = i(e);
122
+ s && typeof s.then == "function" && Promise.resolve(s).catch((a) => this._reportListenerError(a, t));
123
+ } catch (s) {
124
+ this._reportListenerError(s, t);
125
+ }
126
+ }
127
+ }
128
+ _reportListenerError(t, e) {
129
+ var n, i;
130
+ try {
131
+ (i = (n = this._options).onListenerError) == null || i.call(n, t, e);
132
+ } catch {
133
+ }
117
134
  }
118
135
  /**
119
136
  * Выполняет действие hasListeners в рамках ответственности EventBus.
@@ -132,12 +149,11 @@ class P {
132
149
  * Очищает накопленное состояние EventBus.
133
150
  */
134
151
  clear(t) {
135
- var e;
136
- t ? (e = this._listeners.get(t)) == null || e.clear() : this._listeners.clear();
152
+ t ? this._listeners.delete(t) : this._listeners.clear();
137
153
  }
138
154
  }
139
- const xt = new P(Object.keys({}));
140
- class H {
155
+ const wt = new H(Object.keys({}));
156
+ class U {
141
157
  constructor() {
142
158
  o(this, "_subscribers", /* @__PURE__ */ new Set());
143
159
  }
@@ -153,7 +169,7 @@ class H {
153
169
  t();
154
170
  }
155
171
  }
156
- class wt extends H {
172
+ class xt extends U {
157
173
  /**
158
174
  * Создает экземпляр Collection и подготавливает базовое состояние.
159
175
  */
@@ -163,7 +179,7 @@ class wt extends H {
163
179
  o(this, "_indices", /* @__PURE__ */ new Map());
164
180
  o(this, "_rootIds", /* @__PURE__ */ new Set());
165
181
  o(this, "_bus");
166
- this._bus = new P(Object.values(m)), e.length && this.add(e), this._createIndex("id");
182
+ this._bus = new H(Object.values(m)), e.length && this.add(e), this._createIndex("id");
167
183
  }
168
184
  /**
169
185
  * Выполняет действие add в рамках ответственности Collection.
@@ -185,8 +201,8 @@ class wt extends H {
185
201
  const a = typeof s == "string" ? s : s.id, l = this._items.findIndex((u) => u.id === a);
186
202
  if (l !== -1) {
187
203
  const [u] = this._items.splice(l, 1);
188
- this._indices.forEach((c, h) => {
189
- c.delete(u[h]);
204
+ this._indices.forEach((c, f) => {
205
+ c.delete(u[f]);
190
206
  }), u.parentId || this._rootIds.delete(u.id), i.push(u);
191
207
  }
192
208
  }), i.length && (this._bus.emit(m.Remove, i), this.notify());
@@ -251,7 +267,7 @@ class wt extends H {
251
267
  this._bus.off(e, n);
252
268
  }
253
269
  }
254
- class Dt {
270
+ class Et {
255
271
  /**
256
272
  * Создает экземпляр IndexedCollection и подготавливает базовое состояние.
257
273
  */
@@ -488,7 +504,7 @@ class Dt {
488
504
  this._list.pop(), this._indexById.delete(t);
489
505
  }
490
506
  }
491
- class It {
507
+ class Dt {
492
508
  constructor(t) {
493
509
  o(this, "_cap");
494
510
  o(this, "_buf");
@@ -519,7 +535,7 @@ class It {
519
535
  return t;
520
536
  }
521
537
  }
522
- class Et {
538
+ class It {
523
539
  constructor(t) {
524
540
  o(this, "_baseUrl");
525
541
  this._baseUrl = t.baseUrl.replace(/\/+$/, "");
@@ -591,7 +607,7 @@ class Et {
591
607
  return await n.json().catch(() => ({}));
592
608
  }
593
609
  }
594
- class At {
610
+ class Ct {
595
611
  /**
596
612
  * Создает экземпляр DelayedExecutor и подготавливает базовое состояние.
597
613
  */
@@ -631,14 +647,14 @@ class At {
631
647
  this._delayTimer && clearTimeout(this._delayTimer), this._maxTimer && clearTimeout(this._maxTimer), this._delayTimer = null, this._maxTimer = null;
632
648
  }
633
649
  }
634
- function w(r) {
650
+ function x(r) {
635
651
  var t;
636
652
  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
653
  }
638
- function U(r) {
639
- return r instanceof Error ? `${r.name}: ${r.message}` : w(r);
654
+ function E(r) {
655
+ return r instanceof Error ? `${r.name}: ${r.message}` : x(r);
640
656
  }
641
- class Ot {
657
+ class At {
642
658
  /**
643
659
  * Создает экземпляр NamedExecutor и подготавливает базовое состояние.
644
660
  */
@@ -675,7 +691,7 @@ class Ot {
675
691
  const e = this._callbacks.get(t);
676
692
  e && e();
677
693
  } catch (e) {
678
- console.error(`[NamedExecutor] flush error: ${U(e)}`);
694
+ console.error(`[NamedExecutor] flush error: ${E(e)}`);
679
695
  }
680
696
  this._clear(t);
681
697
  }
@@ -699,9 +715,9 @@ class Ot {
699
715
  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
716
  }
701
717
  }
702
- function Ct() {
718
+ function Ot() {
703
719
  return function(r, t) {
704
- f(
720
+ h(
705
721
  ({ value: e }) => {
706
722
  if (typeof e == "string")
707
723
  try {
@@ -712,7 +728,7 @@ function Ct() {
712
728
  return e;
713
729
  },
714
730
  { toClassOnly: !0 }
715
- )(r, t), f(
731
+ )(r, t), h(
716
732
  ({ value: e }) => {
717
733
  try {
718
734
  return JSON.stringify(e);
@@ -726,7 +742,7 @@ function Ct() {
726
742
  }
727
743
  function Mt() {
728
744
  return function(r, t) {
729
- f(
745
+ h(
730
746
  ({ value: e }) => {
731
747
  if (e == null)
732
748
  return "{}";
@@ -739,7 +755,7 @@ function Mt() {
739
755
  return e;
740
756
  },
741
757
  { toClassOnly: !0 }
742
- )(r, t), f(
758
+ )(r, t), h(
743
759
  ({ value: e }) => {
744
760
  if (!e)
745
761
  return {};
@@ -756,7 +772,7 @@ function Mt() {
756
772
  };
757
773
  }
758
774
  const K = Symbol("onDeserialized");
759
- function $t() {
775
+ function Lt() {
760
776
  return function(r, t) {
761
777
  Reflect.defineMetadata(K, t, r);
762
778
  };
@@ -768,19 +784,19 @@ function rt(r) {
768
784
  );
769
785
  return t ? r[t].bind(r) : null;
770
786
  }
771
- function Ft() {
787
+ function $t() {
772
788
  return function(r, t) {
773
- f(
789
+ h(
774
790
  ({ value: e }) => typeof e == "string" ? e.trim() : String(e ?? ""),
775
791
  { toClassOnly: !0 }
776
- )(r, t), f(
792
+ )(r, t), h(
777
793
  ({ value: e }) => typeof e == "string" ? e : String(e ?? ""),
778
794
  { toPlainOnly: !0 }
779
795
  )(r, t);
780
796
  };
781
797
  }
782
- function Lt(r, t) {
783
- return f(({ value: e, type: n }) => {
798
+ function Ft(r, t) {
799
+ return h(({ value: e, type: n }) => {
784
800
  if (!e)
785
801
  return /* @__PURE__ */ new Map();
786
802
  if (n === _.PLAIN_TO_CLASS) {
@@ -802,13 +818,13 @@ function Lt(r, t) {
802
818
  })
803
819
  );
804
820
  }
805
- return console.warn(`[TypeMap] Expected object or array, got ${w(e)}`), /* @__PURE__ */ new Map();
821
+ return console.warn(`[TypeMap] Expected object or array, got ${x(e)}`), /* @__PURE__ */ new Map();
806
822
  }
807
- return n === _.CLASS_TO_PLAIN ? e instanceof Map ? Array.from(e.values()).map((i) => T(i)) : (console.warn(`[TypeMap] Expected Map, got ${w(e)}`), t ? [] : {}) : (console.warn(`[TypeMap] Unexpected transformation type: ${String(n)}`), e);
823
+ 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
824
  });
809
825
  }
810
826
  function kt(r) {
811
- return f(({ value: t, type: e }) => {
827
+ return h(({ value: t, type: e }) => {
812
828
  if (!t || typeof t != "object")
813
829
  return {};
814
830
  if (e === _.PLAIN_TO_CLASS) {
@@ -863,23 +879,23 @@ function Ht(r, t, e) {
863
879
  }
864
880
  function Ut(r) {
865
881
  return function(t, e) {
866
- f(({ value: n }) => n === null ? void 0 : n, { toPlainOnly: !0 })(t, e), Z(r)(t, e);
882
+ h(({ value: n }) => n === null ? void 0 : n, { toPlainOnly: !0 })(t, e), Z(r)(t, e);
867
883
  };
868
884
  }
869
885
  function Kt() {
870
- return f(({ value: r, type: t }) => t === _.PLAIN_TO_CLASS ? r == null ? void 0 : r.id : r);
886
+ return h(({ value: r, type: t }) => t === _.PLAIN_TO_CLASS ? r == null ? void 0 : r.id : r);
871
887
  }
872
888
  function Rt(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);
889
+ return h(({ value: t, type: e }) => e === _.PLAIN_TO_CLASS ? t == null ? void 0 : t.map((n) => n == null ? void 0 : n[r]) : t);
874
890
  }
875
891
  function jt() {
876
- return f(({ value: r, type: t }) => t === _.CLASS_TO_PLAIN && (r == null ? void 0 : r.id) || r);
892
+ return h(({ value: r, type: t }) => t === _.CLASS_TO_PLAIN && (r == null ? void 0 : r.id) || r);
877
893
  }
878
894
  function Bt() {
879
- return f(({ value: r, type: t }) => t === _.CLASS_TO_PLAIN ? r.map((e) => e.id) : r);
895
+ return h(({ value: r, type: t }) => t === _.CLASS_TO_PLAIN ? r.map((e) => e.id) : r);
880
896
  }
881
897
  function Vt() {
882
- return f(({ value: r, type: t }) => t === _.CLASS_TO_PLAIN ? void 0 : r, { toPlainOnly: !0 });
898
+ return h(({ value: r, type: t }) => t === _.CLASS_TO_PLAIN ? void 0 : r, { toPlainOnly: !0 });
883
899
  }
884
900
  function Gt(r, t) {
885
901
  return b(r, t, {
@@ -902,11 +918,11 @@ const Yt = !1;
902
918
  function qt(r, t) {
903
919
  return t();
904
920
  }
905
- const Qt = () => W(), M = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
921
+ const Qt = () => W(), L = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
906
922
  function Xt(r) {
907
923
  let t = "";
908
924
  for (let e = 0; e < r; ++e)
909
- t += M[Math.floor(M.length * Math.random())];
925
+ t += L[Math.floor(L.length * Math.random())];
910
926
  return t;
911
927
  }
912
928
  class vt {
@@ -1016,11 +1032,11 @@ const $ = /* @__PURE__ */ new WeakMap(), it = /* @__PURE__ */ new Set([
1016
1032
  "SymbolLock"
1017
1033
  ]);
1018
1034
  function ee(r) {
1019
- return E(R(r).snapshot);
1035
+ return C(R(r).snapshot);
1020
1036
  }
1021
1037
  function re(r, t) {
1022
1038
  const e = R(r);
1023
- return e.subscribers.add(t), t(E(e.snapshot)), () => e.subscribers.delete(t);
1039
+ return e.subscribers.add(t), t(C(e.snapshot)), () => e.subscribers.delete(t);
1024
1040
  }
1025
1041
  function R(r) {
1026
1042
  var a, l, u;
@@ -1032,17 +1048,17 @@ function R(r) {
1032
1048
  entries: /* @__PURE__ */ new Map(),
1033
1049
  subscribers: /* @__PURE__ */ new Set()
1034
1050
  }, i = (c) => {
1035
- var C;
1036
- const h = c ? {
1051
+ var M;
1052
+ const f = c ? {
1037
1053
  ctrl: c.ctrlKey,
1038
1054
  shift: c.shiftKey,
1039
1055
  alt: c.altKey,
1040
1056
  meta: c.metaKey,
1041
1057
  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
1058
+ altGraph: ((M = c.getModifierState) == null ? void 0 : M.call(c, "AltGraph")) === !0
1043
1059
  } : F(e).modifiers, O = [...n.entries.values()], S = {
1044
1060
  platform: e,
1045
- modifiers: h,
1061
+ modifiers: f,
1046
1062
  held: {
1047
1063
  key: [...new Set(O.map((y) => y.key))].sort(),
1048
1064
  code: [...new Set(O.map((y) => y.code).filter(Boolean))].sort()
@@ -1051,20 +1067,20 @@ function R(r) {
1051
1067
  if (!ot(n.snapshot, S)) {
1052
1068
  n.snapshot = S;
1053
1069
  for (const y of n.subscribers)
1054
- y(E(S));
1070
+ y(C(S));
1055
1071
  }
1056
1072
  }, s = () => {
1057
1073
  n.entries.clear(), i();
1058
1074
  };
1059
1075
  return r.addEventListener("keydown", (c) => {
1060
1076
  if (!it.has(c.key)) {
1061
- const h = c.key.toLowerCase();
1062
- n.entries.set(c.code || `key:${h}`, { key: h, code: c.code });
1077
+ const f = c.key.toLowerCase();
1078
+ n.entries.set(c.code || `key:${f}`, { key: f, code: c.code });
1063
1079
  }
1064
1080
  i(c);
1065
1081
  }, !0), r.addEventListener("keyup", (c) => {
1066
- const h = c.key.toLowerCase();
1067
- n.entries.delete(c.code || `key:${h}`), i(c);
1082
+ const f = c.key.toLowerCase();
1083
+ n.entries.delete(c.code || `key:${f}`), i(c);
1068
1084
  }, !0), r.addEventListener("visibilitychange", () => {
1069
1085
  r.visibilityState === "hidden" && s();
1070
1086
  }), (l = r.defaultView) == null || l.addEventListener("blur", s), (u = r.defaultView) == null || u.addEventListener("pagehide", s), $.set(r, n), n;
@@ -1089,19 +1105,19 @@ function st(r) {
1089
1105
  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
1106
  }
1091
1107
  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 && L(r.held.key, t.held.key) && L(r.held.code, t.held.code);
1108
+ 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);
1093
1109
  }
1094
- function L(r, t) {
1110
+ function k(r, t) {
1095
1111
  return r.length === t.length && r.every((e, n) => e === t[n]);
1096
1112
  }
1097
- function E(r) {
1113
+ function C(r) {
1098
1114
  return {
1099
1115
  platform: r.platform,
1100
1116
  modifiers: { ...r.modifiers },
1101
1117
  held: { key: [...r.held.key], code: [...r.held.code] }
1102
1118
  };
1103
1119
  }
1104
- class ne extends H {
1120
+ class ne extends U {
1105
1121
  constructor() {
1106
1122
  super(...arguments);
1107
1123
  /** Массив всех логов */
@@ -1309,13 +1325,13 @@ function ce(r, t) {
1309
1325
  }
1310
1326
  function le(r, t, e, n) {
1311
1327
  const i = p(r), s = p(t), a = p(e), l = p(n);
1312
- return !z(s, a) && !D(i, l);
1328
+ return !P(s, a) && !D(i, l);
1313
1329
  }
1314
1330
  function ue(r, t, e) {
1315
- return !z(r, p(t)) && !D(r, X(e));
1331
+ return !P(r, p(t)) && !D(r, X(e));
1316
1332
  }
1317
1333
  const fe = (r) => r && new Date(r);
1318
- function de(r, t = "HH:mm dd.MM.yyyy", e = {}) {
1334
+ function he(r, t = "HH:mm dd.MM.yyyy", e = {}) {
1319
1335
  return r && g(r, t, e);
1320
1336
  }
1321
1337
  function ut(r, t = "HH:mm dd.MM.yyyy", e = {}, n = !0) {
@@ -1330,7 +1346,7 @@ function ut(r, t = "HH:mm dd.MM.yyyy", e = {}, n = !0) {
1330
1346
  r = new Date(r.toString());
1331
1347
  return n ? g(r, t, e) : g(I(r, "utc"), t, e);
1332
1348
  }
1333
- function he(r) {
1349
+ function de(r) {
1334
1350
  const t = { weekday: "short" }, e = new Intl.DateTimeFormat("ru-RU", t).format(r);
1335
1351
  return e.charAt(0).toUpperCase() + e.slice(1);
1336
1352
  }
@@ -1349,18 +1365,18 @@ function ye(r) {
1349
1365
  };
1350
1366
  }
1351
1367
  function pe(r, t) {
1352
- const e = N(r, t), { hours: n, minutes: i } = A(e);
1368
+ const e = z(r, t), { hours: n, minutes: i } = A(e);
1353
1369
  return n || i ? `${e > 0 ? "-" : "+"}${d(n)}:${d(i)}` : "";
1354
1370
  }
1355
1371
  function ge(r, t) {
1356
- const e = N(r, t), { hours: n, minutes: i } = A(e);
1372
+ const e = z(r, t), { hours: n, minutes: i } = A(e);
1357
1373
  return n || i ? `${e > 0 ? "-" : ""}${d(n)}:${d(i)}` : "";
1358
1374
  }
1359
- function k(r = /* @__PURE__ */ new Date()) {
1375
+ function N(r = /* @__PURE__ */ new Date()) {
1360
1376
  return new Date(r.getFullYear(), r.getMonth(), r.getDate());
1361
1377
  }
1362
1378
  function be(r, t) {
1363
- const e = q(k(r), k(t));
1379
+ const e = q(N(r), N(t));
1364
1380
  return e ? e > 7 ? {
1365
1381
  variant: "red",
1366
1382
  value: ">7"
@@ -1388,17 +1404,17 @@ function Se(r) {
1388
1404
  return null;
1389
1405
  const e = t.match(/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2})(?::(\d{2}))?$/);
1390
1406
  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();
1407
+ 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);
1408
+ return Number.isNaN(f.getTime()) ? null : f.toISOString();
1393
1409
  }
1394
1410
  const n = new Date(t);
1395
1411
  return Number.isNaN(n.getTime()) ? null : n.toISOString();
1396
1412
  }
1397
- function xe(r) {
1413
+ function we(r) {
1398
1414
  const t = String(r ?? "").trim();
1399
1415
  return t ? t.slice(0, 10) : "";
1400
1416
  }
1401
- function we(r) {
1417
+ function xe(r) {
1402
1418
  const t = String(r ?? "").trim();
1403
1419
  if (!t)
1404
1420
  return "";
@@ -1408,7 +1424,7 @@ function we(r) {
1408
1424
  const n = e.getFullYear(), i = d(e.getMonth() + 1), s = d(e.getDate()), a = d(e.getHours()), l = d(e.getMinutes());
1409
1425
  return `${n}-${i}-${s}T${a}:${l}`;
1410
1426
  }
1411
- function De(r, t) {
1427
+ function Ee(r, t) {
1412
1428
  const e = j(r);
1413
1429
  if (e)
1414
1430
  return e;
@@ -1418,7 +1434,7 @@ function De(r, t) {
1418
1434
  const i = B(t), s = i ? I(n, i) : n;
1419
1435
  return `${d(s.getHours())}:${d(s.getMinutes())}`;
1420
1436
  }
1421
- function Ie(r, t, e) {
1437
+ function De(r, t, e) {
1422
1438
  const n = j(t).match(/^(\d{2}):(\d{2})$/);
1423
1439
  if (!n)
1424
1440
  return null;
@@ -1456,7 +1472,7 @@ function B(r) {
1456
1472
  return null;
1457
1473
  }
1458
1474
  }
1459
- function Ee(r) {
1475
+ function Ie(r) {
1460
1476
  if (r == null)
1461
1477
  return null;
1462
1478
  const t = String(r).trim();
@@ -1468,11 +1484,11 @@ function Ee(r) {
1468
1484
  const n = t.match(/^(\d{2}):(\d{2})$/);
1469
1485
  return n ? `${n[1]}:${n[2]}:00` : null;
1470
1486
  }
1471
- function Ae(r) {
1472
- const t = dt(r), e = Math.sign(t) >= 0 ? "" : "-", { hours: n, minutes: i } = A(t);
1487
+ function Ce(r) {
1488
+ const t = ht(r), e = Math.sign(t) >= 0 ? "" : "-", { hours: n, minutes: i } = A(t);
1473
1489
  return `${e}${d(n)}:${d(i)}`;
1474
1490
  }
1475
- function Oe(r = null, t = "dd", e = {}) {
1491
+ function Ae(r = null, t = "dd", e = {}) {
1476
1492
  const n = ft(r);
1477
1493
  if (!n)
1478
1494
  return "";
@@ -1492,7 +1508,7 @@ function A(r) {
1492
1508
  minutes: Math.floor(t / 60) % 60
1493
1509
  };
1494
1510
  }
1495
- function dt(r) {
1511
+ function ht(r) {
1496
1512
  const t = String(r ?? "").trim();
1497
1513
  if (!t)
1498
1514
  return 0;
@@ -1509,12 +1525,12 @@ function dt(r) {
1509
1525
  function d(r) {
1510
1526
  return String(r).padStart(2, "0");
1511
1527
  }
1512
- function Ce(r) {
1528
+ function Oe(r) {
1513
1529
  const t = /* @__PURE__ */ new Date();
1514
1530
  try {
1515
- const e = x(r, t), n = Intl.supportedValuesOf("timeZone");
1531
+ const e = w(r, t), n = Intl.supportedValuesOf("timeZone");
1516
1532
  for (const i of n)
1517
- if (x(i, t) === e)
1533
+ if (w(i, t) === e)
1518
1534
  return i;
1519
1535
  } catch {
1520
1536
  return null;
@@ -1522,9 +1538,9 @@ function Ce(r) {
1522
1538
  return null;
1523
1539
  }
1524
1540
  function Me(r) {
1525
- return x(r, /* @__PURE__ */ new Date());
1541
+ return w(r, /* @__PURE__ */ new Date());
1526
1542
  }
1527
- class $e {
1543
+ class Le {
1528
1544
  constructor(t) {
1529
1545
  o(this, "_url");
1530
1546
  o(this, "_retryInterval");
@@ -1535,14 +1551,23 @@ class $e {
1535
1551
  this._url = t.url, this._retryInterval = t.retryInterval ?? 3e3, this._options = t;
1536
1552
  }
1537
1553
  start() {
1538
- this._abortController = new AbortController(), this._connect();
1554
+ if (this._abortController)
1555
+ return;
1556
+ const t = new AbortController();
1557
+ this._abortController = t, this._connect(t);
1539
1558
  }
1540
1559
  stop() {
1541
- var t;
1542
- this._clearReconnect(), this._isConnected = !1, (t = this._abortController) == null || t.abort(), this._abortController = null;
1560
+ this._clearReconnect(), this._isConnected = !1;
1561
+ const t = this._abortController;
1562
+ this._abortController = null, t == null || t.abort();
1563
+ }
1564
+ _isCurrent(t) {
1565
+ return this._abortController === t && !t.signal.aborted;
1543
1566
  }
1544
- _scheduleReconnect() {
1545
- this._clearReconnect(), this._reconnectTimeout = setTimeout(() => this.start(), this._retryInterval);
1567
+ _scheduleReconnect(t) {
1568
+ this._isCurrent(t) && (this._clearReconnect(), this._reconnectTimeout = setTimeout(() => {
1569
+ this._isCurrent(t) && (this.stop(), this.start());
1570
+ }, this._retryInterval));
1546
1571
  }
1547
1572
  _clearReconnect() {
1548
1573
  this._reconnectTimeout && (clearTimeout(this._reconnectTimeout), this._reconnectTimeout = null);
@@ -1552,48 +1577,62 @@ class $e {
1552
1577
  const t = { ...this._options.headers }, e = await ((i = (n = this._options).getToken) == null ? void 0 : i.call(n));
1553
1578
  return e && (t.Authorization = `Bearer ${e}`), t;
1554
1579
  }
1555
- async _connect() {
1556
- var t, e, n;
1580
+ async _connect(t) {
1581
+ var e, n;
1557
1582
  try {
1583
+ const i = await this._buildHeaders();
1584
+ if (!this._isCurrent(t))
1585
+ return;
1558
1586
  await tt(this._url, {
1559
1587
  method: "GET",
1560
- headers: await this._buildHeaders(),
1561
- signal: (t = this._abortController) == null ? void 0 : t.signal,
1588
+ headers: i,
1589
+ signal: t.signal,
1562
1590
  openWhenHidden: !0,
1563
- onopen: async (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);
1591
+ onopen: async (s) => {
1592
+ var l, u, c, f;
1593
+ if (!this._isCurrent(t))
1594
+ throw new Error("[SSEManager] Connection was stopped.");
1595
+ if (s.ok && ((u = (l = s.headers.get("content-type")) == null ? void 0 : l.split(";")[0]) == null ? void 0 : u.trim()) === et) {
1596
+ this._isConnected = !0, (f = (c = this._options).onOpen) == null || f.call(c);
1567
1597
  return;
1568
1598
  }
1569
- throw new Error(`Unexpected response: ${i.status}`);
1599
+ throw new Error(`Unexpected response: ${s.status}`);
1570
1600
  },
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
- }
1601
+ onmessage: (s) => {
1602
+ if (this._isCurrent(t))
1603
+ try {
1604
+ this._options.onEvent(JSON.parse(s.data));
1605
+ } catch (a) {
1606
+ console.warn(`[SSEManager] Failed to parse message: ${E(a)}`);
1607
+ }
1577
1608
  },
1578
1609
  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
1610
  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();
1611
+ this._isCurrent(t) && (this._isConnected = !1, (a = (s = this._options).onClose) == null || a.call(s));
1612
+ },
1613
+ // Retry belongs to this manager. Throwing disables the library's retry loop.
1614
+ onerror: (s) => {
1615
+ throw s;
1585
1616
  }
1586
1617
  });
1587
1618
  } 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();
1619
+ if (this._isCurrent(t)) {
1620
+ this._isConnected = !1;
1621
+ try {
1622
+ (n = (e = this._options).onError) == null || n.call(e, i instanceof Error ? i : new Error(String(i)));
1623
+ } catch (s) {
1624
+ console.warn(`[SSEManager] Error callback failed: ${E(s)}`);
1625
+ }
1626
+ }
1627
+ } finally {
1628
+ this._isCurrent(t) && (this._isConnected = !1, this._scheduleReconnect(t));
1590
1629
  }
1591
1630
  }
1592
1631
  get isConnected() {
1593
1632
  return this._isConnected;
1594
1633
  }
1595
1634
  }
1596
- class Fe {
1635
+ class $e {
1597
1636
  constructor() {
1598
1637
  o(this, "_currentCount", 0);
1599
1638
  o(this, "_lastResetTime", Date.now());
@@ -1612,40 +1651,40 @@ class Fe {
1612
1651
  }
1613
1652
  export {
1614
1653
  Ht as AfterDeserialize,
1615
- xt as AppBus,
1654
+ wt as AppBus,
1616
1655
  Pt as BeforeSerialize,
1617
- wt as Collection,
1618
- At as DelayedExecutor,
1656
+ xt as Collection,
1657
+ Ct as DelayedExecutor,
1619
1658
  Rt as DeserializeArrayField,
1620
1659
  Kt as DeserializeId,
1621
- P as EventBus,
1660
+ H as EventBus,
1622
1661
  m as Events,
1623
1662
  zt as GenericExpose,
1624
1663
  vt as HotkeyManager,
1625
1664
  Yt as IS_DEBUG,
1626
1665
  Vt as IgnoreToPlain,
1627
- Dt as IndexedCollection,
1666
+ Et as IndexedCollection,
1628
1667
  Ut as IsOptionalTransformed,
1629
- Ct as Json,
1668
+ Ot as Json,
1630
1669
  Mt as JsonString,
1631
- Ot as NamedExecutor,
1632
- Et as PayloadHttpClient,
1633
- It as RingBuffer,
1634
- $e as SSEManager,
1635
- Ft as Script,
1670
+ At as NamedExecutor,
1671
+ It as PayloadHttpClient,
1672
+ Dt as RingBuffer,
1673
+ Le as SSEManager,
1674
+ $t as Script,
1636
1675
  Nt as Serialize,
1637
1676
  jt as SerializeId,
1638
1677
  Bt as SerializeIds,
1639
1678
  ne as StructuredLogger,
1640
- H as Subscribable,
1679
+ U as Subscribable,
1641
1680
  lt as SystemClock,
1642
- Lt as TypeMap,
1681
+ Ft as TypeMap,
1643
1682
  kt as TypeRecord,
1644
- Fe as UPSMeter_Service,
1683
+ $e as UPSMeter_Service,
1645
1684
  ae as capitalize,
1646
1685
  Wt as compareNumber,
1647
- U as consoleErrorSummary,
1648
- w as consoleValueSummary,
1686
+ E as consoleErrorSummary,
1687
+ x as consoleValueSummary,
1649
1688
  ie as createInstance,
1650
1689
  pe as diffDuration,
1651
1690
  ge as diffDurationTable,
@@ -1653,12 +1692,12 @@ export {
1653
1692
  me as extractTime,
1654
1693
  ye as findMinMaxDates,
1655
1694
  _e as formatDateToMSK,
1656
- de as formatDatetime,
1695
+ he as formatDatetime,
1657
1696
  ut as formatDatetimeTZ,
1658
- Oe as formatDatetimeTZSpecial,
1697
+ Ae as formatDatetimeTZSpecial,
1659
1698
  Qt as generateUUID,
1660
1699
  be as getDateOnlyDiffFactor,
1661
- he as getDayOfWeek,
1700
+ de as getDayOfWeek,
1662
1701
  ee as getKeyboardStateSnapshot,
1663
1702
  rt as getOnDeserializedMethod,
1664
1703
  Me as getTimezoneOffsetMs,
@@ -1669,22 +1708,22 @@ export {
1669
1708
  ue as isDateInRange,
1670
1709
  le as isDateRangeOverlap,
1671
1710
  Zt as isNullOrUndefined,
1672
- De as isoDateTimeToTimeInput,
1673
- xe as isoToDateInput,
1674
- we as isoToDateTimeLocalInput,
1675
- Ie as mergeTimeIntoDateTime,
1676
- $t as onDeserialized,
1711
+ Ee as isoDateTimeToTimeInput,
1712
+ we as isoToDateInput,
1713
+ xe as isoToDateTimeLocalInput,
1714
+ De as mergeTimeIntoDateTime,
1715
+ Lt as onDeserialized,
1677
1716
  fe as parseDate,
1678
- Ae as parseDuration,
1679
- Ce as parseOffsetToTimezone,
1717
+ Ce as parseDuration,
1718
+ Oe as parseOffsetToTimezone,
1680
1719
  qt as profile,
1681
1720
  Xt as randomString,
1682
- k as removeTime,
1721
+ N as removeTime,
1683
1722
  re as subscribeKeyboardState,
1684
1723
  j as timeToTimeInput,
1685
1724
  Gt as toInstance,
1686
1725
  Te as toIsoZDate,
1687
1726
  Se as toIsoZDateTime,
1688
1727
  Jt as toPlain,
1689
- Ee as toTimeHHMMSS
1728
+ Ie as toTimeHHMMSS
1690
1729
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@endge/utils",
3
3
  "type": "module",
4
- "version": "0.26.0",
4
+ "version": "0.27.0",
5
5
  "private": false,
6
6
  "sideEffects": false,
7
7
  "exports": {