@pravosleva/reactive-engine 1.7.1 → 1.8.0-beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/dist/angular/ReactiveEngine4Angular.cjs +1 -1
  2. package/dist/angular/ReactiveEngine4Angular.cjs.map +1 -1
  3. package/dist/angular/ReactiveEngine4Angular.d.ts +16 -7
  4. package/dist/angular/ReactiveEngine4Angular.d.ts.map +1 -1
  5. package/dist/angular/ReactiveEngine4Angular.mjs +4 -4
  6. package/dist/angular/ReactiveEngine4Angular.mjs.map +1 -1
  7. package/dist/angular/core.angular.auto.test.d.ts +2 -0
  8. package/dist/angular/core.angular.auto.test.d.ts.map +1 -0
  9. package/dist/angular/core.angular.test.d.ts +2 -0
  10. package/dist/angular/core.angular.test.d.ts.map +1 -0
  11. package/dist/angular/index.cjs +1 -1
  12. package/dist/angular/index.d.ts +2 -2
  13. package/dist/angular/index.d.ts.map +1 -1
  14. package/dist/angular/index.mjs +1 -1
  15. package/dist/angular/rxjs-interop.d.ts +1 -1
  16. package/dist/angular/rxjs-interop.d.ts.map +1 -1
  17. package/dist/core/AbstractService.d.ts +3 -3
  18. package/dist/core/core.auto.test.d.ts +2 -0
  19. package/dist/core/core.auto.test.d.ts.map +1 -0
  20. package/dist/core/core.d.ts +105 -366
  21. package/dist/core/core.d.ts.map +1 -1
  22. package/dist/core/types.d.ts +102 -72
  23. package/dist/core/types.d.ts.map +1 -1
  24. package/dist/core.cjs +1 -1
  25. package/dist/core.cjs.map +1 -1
  26. package/dist/core.mjs +492 -421
  27. package/dist/core.mjs.map +1 -1
  28. package/dist/index.cjs +1 -1
  29. package/dist/index.mjs +11 -11
  30. package/dist/react/ReactiveEngine4React.cjs +1 -1
  31. package/dist/react/ReactiveEngine4React.cjs.map +1 -1
  32. package/dist/react/ReactiveEngine4React.d.ts +16 -8
  33. package/dist/react/ReactiveEngine4React.d.ts.map +1 -1
  34. package/dist/react/ReactiveEngine4React.mjs +5 -5
  35. package/dist/react/ReactiveEngine4React.mjs.map +1 -1
  36. package/dist/react/core.react.auto.test.d.ts +2 -0
  37. package/dist/react/core.react.auto.test.d.ts.map +1 -0
  38. package/dist/react/hooks/FilteredCatalog.auto.test.d.ts +2 -0
  39. package/dist/react/hooks/FilteredCatalog.auto.test.d.ts.map +1 -0
  40. package/dist/react/hooks/useReactiveSubscription/useReactiveSubscription.auto.test.d.ts +2 -0
  41. package/dist/react/hooks/useReactiveSubscription/useReactiveSubscription.auto.test.d.ts.map +1 -0
  42. package/dist/react/hooks/useReactiveValue/useReactiveValue.auto.test.d.ts +2 -0
  43. package/dist/react/hooks/useReactiveValue/useReactiveValue.auto.test.d.ts.map +1 -0
  44. package/dist/react/index.cjs +1 -1
  45. package/dist/react/index.d.ts +2 -2
  46. package/dist/react/index.d.ts.map +1 -1
  47. package/dist/react/index.mjs +1 -1
  48. package/dist/reactive-engine.umd.js +2 -2
  49. package/dist/reactive-engine.umd.js.map +1 -1
  50. package/dist/vue/ReactiveEngine4Vue.cjs +1 -1
  51. package/dist/vue/ReactiveEngine4Vue.cjs.map +1 -1
  52. package/dist/vue/ReactiveEngine4Vue.d.ts +21 -13
  53. package/dist/vue/ReactiveEngine4Vue.d.ts.map +1 -1
  54. package/dist/vue/ReactiveEngine4Vue.mjs +27 -17
  55. package/dist/vue/ReactiveEngine4Vue.mjs.map +1 -1
  56. package/dist/vue/composables/useReactiveValue.auto.test.d.ts +2 -0
  57. package/dist/vue/composables/useReactiveValue.auto.test.d.ts.map +1 -0
  58. package/dist/vue/core.vue.auto.test.d.ts +2 -0
  59. package/dist/vue/core.vue.auto.test.d.ts.map +1 -0
  60. package/dist/vue/core.vue.test.d.ts +2 -0
  61. package/dist/vue/core.vue.test.d.ts.map +1 -0
  62. package/dist/vue/index.cjs +1 -1
  63. package/dist/vue/index.d.ts +1 -1
  64. package/dist/vue/index.d.ts.map +1 -1
  65. package/dist/vue/index.mjs +1 -1
  66. package/package.json +1 -1
  67. package/dist/angular/ReactiveEngine4Angular.test.d.ts +0 -2
  68. package/dist/angular/ReactiveEngine4Angular.test.d.ts.map +0 -1
  69. package/dist/decorators/withThrottleComputed/_withThrottleComputed.d.ts +0 -22
  70. package/dist/decorators/withThrottleComputed/_withThrottleComputed.d.ts.map +0 -1
  71. package/dist/utils/getExtractedValues.cjs +0 -2
  72. package/dist/utils/getExtractedValues.cjs.map +0 -1
  73. package/dist/utils/getExtractedValues.mjs +0 -24
  74. package/dist/utils/getExtractedValues.mjs.map +0 -1
  75. package/dist/vue/ReactiveEngine4Vue.test.d.ts +0 -2
  76. package/dist/vue/ReactiveEngine4Vue.test.d.ts.map +0 -1
package/dist/core.mjs CHANGED
@@ -1,115 +1,236 @@
1
- import { getExtractedValues as e } from "./utils/getExtractedValues.mjs";
2
1
  //#region src/core/core.ts
3
- var t = class {
2
+ var e = class {
4
3
  frameworkPrefix = "core";
5
- activeEffect = null;
6
- isBatching = !1;
4
+ activeConsumer = null;
5
+ subscriberId = 0;
6
+ batchDepth = 0;
7
7
  pendingEffects = /* @__PURE__ */ new Set();
8
+ allEffects = /* @__PURE__ */ new Set();
9
+ computedCache = /* @__PURE__ */ new Map();
10
+ computed(e, t) {
11
+ let n = this;
12
+ if (n.computedCache.has(e)) {
13
+ let t = n.computedCache.get(e)?.deref();
14
+ if (t) return t;
15
+ }
16
+ let r = t || "unnamed_computed", i, a = /* @__PURE__ */ new Set(), o = {
17
+ id: ++n.subscriberId,
18
+ isDirty: !0,
19
+ cleanups: /* @__PURE__ */ new Set(),
20
+ markDirty() {
21
+ this.isDirty || (this.isDirty = !0, Array.from(a).forEach((e) => {
22
+ e !== n.activeConsumer && e.markDirty();
23
+ }));
24
+ }
25
+ }, s = {
26
+ get value() {
27
+ if (n.activeConsumer) {
28
+ let e = n.activeConsumer;
29
+ a.has(e) || (a.add(e), e.cleanups.add(() => a.delete(e)));
30
+ }
31
+ if (o.isDirty) {
32
+ let t = Array.from(o.cleanups);
33
+ o.cleanups.clear(), t.forEach((e) => e());
34
+ let r = n.activeConsumer;
35
+ n.activeConsumer = o;
36
+ try {
37
+ i = e(), o.isDirty = !1;
38
+ } finally {
39
+ n.activeConsumer = r;
40
+ }
41
+ }
42
+ return i;
43
+ },
44
+ subscribe: (e) => n.effect(() => e(s.value), `computed:use:${r}`),
45
+ destroy() {
46
+ let t = Array.from(o.cleanups);
47
+ o.cleanups.clear(), t.forEach((e) => e()), a.clear(), n.computedCache.delete(e);
48
+ for (let [e, t] of n.computedCache.entries()) t.deref() === s && n.computedCache.delete(e);
49
+ }
50
+ };
51
+ return n.cleanupRegistry && n.cleanupRegistry.register(s, () => s.destroy()), n.computedCache.set(e, new WeakRef(s)), s;
52
+ }
53
+ effect(e, t) {
54
+ let n = this, r = {
55
+ id: ++n.subscriberId,
56
+ label: t,
57
+ cleanups: /* @__PURE__ */ new Set(),
58
+ markDirty() {
59
+ n.pendingEffects.add(r), n.batchDepth === 0 && n.flushEffects();
60
+ },
61
+ run() {
62
+ let t = Array.from(r.cleanups);
63
+ r.cleanups.clear(), t.forEach((e) => {
64
+ try {
65
+ e();
66
+ } catch (e) {
67
+ console.error("[Reactive Engine:Cleanup Error]", e);
68
+ }
69
+ });
70
+ let i = n.activeConsumer;
71
+ n.activeConsumer = r;
72
+ try {
73
+ let t = e();
74
+ typeof t == "function" && r.cleanups.add(t);
75
+ } catch (e) {
76
+ console.error("[Reactive Error] Ошибка при выполнении тела эффекта:", e);
77
+ } finally {
78
+ n.activeConsumer = i;
79
+ }
80
+ }
81
+ };
82
+ return n.allEffects.add(r), r.run(), () => {
83
+ Array.from(r.cleanups).forEach((e) => {
84
+ try {
85
+ e();
86
+ } catch (e) {
87
+ console.error("[Reactive Engine:Dispose Cleanup Error]", e);
88
+ }
89
+ }), r.cleanups.clear(), n.pendingEffects.delete(r), n.allEffects.delete(r);
90
+ };
91
+ }
92
+ signal(e, t) {
93
+ let n = this, r = e, i = /* @__PURE__ */ new Set(), a = typeof t == "string" ? { name: t } : t || {}, o = a.name || "unnamed_signal";
94
+ return {
95
+ get value() {
96
+ if (n.activeConsumer) {
97
+ let e = n.activeConsumer;
98
+ i.has(e) || (i.add(e), e.cleanups.add(() => i.delete(e)));
99
+ }
100
+ return r;
101
+ },
102
+ set value(e) {
103
+ if (a?.validate) {
104
+ let t = a.validate(e);
105
+ if (t !== !0) {
106
+ console.error(`[Reactive Engine: Validation Error] ${t}`);
107
+ return;
108
+ }
109
+ }
110
+ if ((e === null || typeof e != "object" && typeof e != "function") && r === e) return;
111
+ let t = r;
112
+ r = e, n.onSignalChange?.(o, e, t), Array.from(i).forEach((e) => {
113
+ e !== n.activeConsumer && e.markDirty();
114
+ });
115
+ },
116
+ subscribe(e) {
117
+ return n.effect(() => e(this.value), `use:${o}`);
118
+ }
119
+ };
120
+ }
121
+ batch(e) {
122
+ this.batchDepth++;
123
+ try {
124
+ e();
125
+ } finally {
126
+ this.batchDepth--, this.batchDepth === 0 && this.flushEffects();
127
+ }
128
+ }
129
+ flushEffects() {
130
+ let e = Array.from(this.pendingEffects);
131
+ this.pendingEffects.clear(), e.forEach((e) => {
132
+ e.run();
133
+ });
134
+ }
135
+ untrack(e) {
136
+ let t = this.activeConsumer;
137
+ this.activeConsumer = null;
138
+ try {
139
+ return e();
140
+ } finally {
141
+ this.activeConsumer = t;
142
+ }
143
+ }
144
+ }, t = class extends e {
8
145
  services = /* @__PURE__ */ new Map();
9
146
  factories = /* @__PURE__ */ new Map();
10
147
  proxyCache = /* @__PURE__ */ new WeakMap();
11
- allEffects = /* @__PURE__ */ new Set();
12
148
  loggerOptions;
13
149
  pendingLogQueue = [];
14
- lastTransactionDuration = null;
15
150
  signalMutationCounts = /* @__PURE__ */ new Map();
16
151
  lastComputedDurations = /* @__PURE__ */ new Map();
17
152
  effectExecutionCounts = /* @__PURE__ */ new Map();
18
153
  batchTickCounts = 0;
154
+ lastTransactionDuration = null;
19
155
  constructor(e) {
20
- this.loggerOptions = e?.logger;
156
+ super(), this.loggerOptions = e?.logger;
21
157
  }
22
- log(t, n, r) {
23
- if (!this.loggerOptions?.isEnabled) return;
24
- if (!this.loggerOptions?.isCoreOptimizationDebugEnabled) {
25
- let t = e({
26
- expectedKey: "CORE_INTERNAL_SIGNAL",
27
- tested: [n],
28
- valueType: "number"
29
- })?.[0] === "1", r = e({
30
- expectedKey: "CORE_INTERNAL_EFFECT",
31
- tested: [n],
32
- valueType: "number"
33
- })?.[0] === "1";
34
- if (t || r) return;
35
- }
36
- if (this.loggerOptions.filter && !(this.loggerOptions.filter instanceof RegExp ? this.loggerOptions.filter : new RegExp(this.loggerOptions.filter.replace(/^\/|\/$/g, ""))).test(n)) return;
37
- let i = {
38
- signal: "background: #007acc; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;",
39
- computed: "background: #42b883; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;",
40
- effect: "background: #e01e5a; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;",
41
- batch: "background: #7952b3; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;",
42
- resource: "background: #d97706; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;",
43
- reactive: "background: #007acc; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;"
44
- }, a = "", o = "color: #aaa; font-weight: normal;";
45
- switch (t) {
46
- case "signal": {
47
- let s = e({
48
- tested: [n],
49
- expectedKey: "CORE_INTERNAL_SIGNAL",
50
- valueType: "number"
51
- })?.[0] === "1", c = n, l = (this.signalMutationCounts.get(c) || 0) + 1;
52
- this.signalMutationCounts.set(c, l);
53
- let u = r, d = u.subscribers && u.subscribers.length > 0 ? u.subscribers.every((t) => t ? e({
54
- tested: [t],
55
- expectedKey: "IS_OPTIMIZED",
56
- valueType: "number"
57
- })?.[0] === "1" : !1) : !1, f = l > 50, p = s ? "COMPUTED_INTERNAL" : "SIGNAL";
58
- a = ` 🔄 Изменений ${s ? "кэша" : "сигнала"}: ${l}${f ? " ⚠️ (high noise — обнаружен дребезг/спам значений!)" : ""}`, f && (o = "color: orange; font-weight: bold;", d || (r.__performance_advice__ = {
59
- issue: `Сигнал [${c}] обновляется слишком часто (${l} раз за такт). Это приводит к избыточным ререндерам UI.`,
60
- solution: "Оберните чтение этого сигнала в декоратор сжатия потока данных 'withThrottleComputed'",
61
- example: "public throttled = withThrottleComputed(this.engine, () => this.yourSignalName.value, { limit: 300 });"
62
- })), console.groupCollapsed(`%c${p}%c [${c}]%c${a}`, s ? "background: #42b883; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;" : i[t], "color: #aaa; font-weight: bold;", o), console.log("Данные (Payload):", r), this.loggerOptions.traceTime && typeof performance < "u" && console.log("Тайминг рантайма:", `${performance.now().toFixed(2)} ms`), console.groupEnd();
63
- return;
64
- }
65
- case "computed": {
66
- let e = r;
67
- if (e && "to" in e) {
68
- let t = e.to;
69
- a = ` 🧮 Значение: ${typeof t == "object" && t ? "{...}" : String(t)}`;
70
- } else if (e && "duration" in e) {
71
- let t = parseFloat(e.duration);
72
- if (!isNaN(t)) {
73
- let r = this.lastComputedDurations.get(n);
74
- if (r !== void 0 && r > 0) {
75
- let n = (t - r) / r * 100;
76
- n > 5 ? (a = ` 🔴 Замедление: +${n.toFixed(1)}% (${e.duration})`, o = "color: #e01e5a; font-weight: bold;") : n < -5 ? (a = ` 🟢 Ускорение: ${n.toFixed(1)}% (${e.duration})`, o = "color: #42b883; font-weight: bold;") : (a = ` 🟢 Стабильно (${e.duration})`, o = "color: #42b883; font-weight: bold;");
77
- } else a = ` ⚪ Первый расчет (${e.duration})`;
78
- this.lastComputedDurations.set(n, t);
158
+ reactive(e, t = "reactive") {
159
+ if (this.proxyCache.has(e)) return this.proxyCache.get(e);
160
+ let n = this, r = /* @__PURE__ */ new Map(), i = !1, a = new Proxy(e, {
161
+ get(e, o, s) {
162
+ if (o === "__subscribe") return (e) => {
163
+ let t = !1;
164
+ return n.effect(() => {
165
+ try {
166
+ JSON.stringify(a);
167
+ } catch {
168
+ Object.values(a);
169
+ }
170
+ typeof window < "u" && (window.__VUE__ || globalThis.__VUE__ || e.toString().includes("triggerRef")) ? t || (t = !0, queueMicrotask(() => {
171
+ t = !1, e();
172
+ })) : e();
173
+ }, "framework-proxy-internal-subscription");
174
+ };
175
+ if (n.activeConsumer) {
176
+ let e = n.activeConsumer;
177
+ r.has(o) || r.set(o, /* @__PURE__ */ new Map());
178
+ let t = r.get(o);
179
+ if (!t.has(e)) {
180
+ let n = () => {
181
+ t.delete(e);
182
+ };
183
+ t.set(e, n), e.cleanups.add(n);
79
184
  }
80
185
  }
81
- break;
82
- }
83
- case "effect": {
84
- let e = (this.effectExecutionCounts.get(n) || 0) + 1;
85
- this.effectExecutionCounts.set(n, e);
86
- let t = e > 30, i = r;
87
- a = ` 🟢 Стабильно${i && "duration" in i ? ` (${i.duration})` : ""} | 🚀 Вызовов: ${e}${t ? " ⚠️ (heavy re-renders)" : ""}`, o = "color: #42b883; font-weight: bold;", t && (o = "color: #ff4a4a; font-weight: bold;");
88
- break;
89
- }
90
- case "batch":
91
- this.batchTickCounts += 1, a = ` 📦 Номер транзакции: #${this.batchTickCounts}`;
92
- break;
93
- case "resource": {
94
- let e = r;
95
- if (e.loading) a = " ⏳ ЗАГРУЗКА (fetching...)", o = "color: #d97706; font-weight: bold;";
96
- else if (e.error) a = ` 🔴 ОШИБКА: ${e.error.message || "Unknown Error"}`, o = "color: #ff4a4a; font-weight: bold;";
97
- else {
98
- let t = e.data;
99
- a = ` 🟢 УСПЕХ (data: ${typeof t == "object" && t ? "{...}" : String(t)})`, o = "color: #42b883; font-weight: bold;";
186
+ if (Array.isArray(e) && typeof o == "string" && [
187
+ "push",
188
+ "pop",
189
+ "shift",
190
+ "unshift",
191
+ "splice",
192
+ "sort",
193
+ "reverse"
194
+ ].includes(o)) {
195
+ let t = e[o];
196
+ return function(...a) {
197
+ n.batchDepth++, i = !0;
198
+ let s = t.apply(e, a);
199
+ return i = !1, r.forEach((e, t) => {
200
+ t !== o && Array.from(e.keys()).forEach((e) => {
201
+ e !== n.activeConsumer && e.markDirty();
202
+ });
203
+ }), n.batchDepth--, n.batchDepth === 0 && n.flushEffects(), s;
204
+ };
205
+ }
206
+ let c = Reflect.get(e, o, s);
207
+ return typeof c == "object" && c ? n.reactive(c, `${t}.${String(o)}`) : c;
208
+ },
209
+ set(e, a, o, s) {
210
+ let c = Reflect.get(e, a, s);
211
+ if (c === o || (Reflect.set(e, a, o, s), n.onSignalChange?.(`${t}.${String(a)}`, o, c), i)) return !0;
212
+ let l = r.get(a), u = l ? Array.from(l.keys()) : [];
213
+ if (Array.isArray(e)) {
214
+ let e = r.get("length");
215
+ e && u.push(...Array.from(e.keys()));
100
216
  }
101
- break;
217
+ return u.forEach((e) => {
218
+ e !== n.activeConsumer && e.markDirty();
219
+ }), typeof n.queueLog == "function" && n.queueLog("reactive", `${t}.${String(a)}`, {
220
+ action: "set",
221
+ property: String(a),
222
+ oldValue: c,
223
+ newValue: o
224
+ }), !0;
102
225
  }
103
- default: break;
104
- }
105
- console.groupCollapsed(`%c${t.toUpperCase()}%c [${n}]%c${a}`, i[t], "color: #aaa; font-weight: bold;", o), console.log("Данные (Payload):", r), this.loggerOptions.traceTime && typeof performance < "u" && console.log("Тайминг рантайма:", `${performance.now().toFixed(2)} ms`), console.groupEnd();
226
+ });
227
+ return this.proxyCache.set(e, a), a;
106
228
  }
107
- onSignalChange;
108
229
  provide(e, t) {
109
- typeof t == "function" && !t.prototype ? this.factories.set(e, t) : this.services.set(e, t);
230
+ typeof t == "function" && (!t.prototype || t.name === "mockConstructor" || t._isMockFunction) ? this.factories.set(e, t) : this.services.set(e, t);
110
231
  }
111
232
  inject(e) {
112
- if (!e) throw Error("[DI Error]: Вы пытаетесь внедрить пустой токен (undefined/null). Проверьте импорты.");
233
+ if (!e) throw Error("[DI Error]: Вы пытаетесь внедрить пустой токен.");
113
234
  let t = e;
114
235
  if (this.services.has(t)) return this.services.get(t);
115
236
  try {
@@ -123,391 +244,341 @@ var t = class {
123
244
  return this.services.set(t, n), n;
124
245
  }
125
246
  throw Error(`Service not found: ${String(e)}`);
126
- } catch (t) {
127
- throw Error(`[DI Error]: Не удалось создать сервис ${String(e)}. Ошибка: ${t?.message || "No e?.message"}`);
247
+ } catch {
248
+ throw Error(`[DI Error]: Не удалось создать сервис ${String(e)}.`);
128
249
  }
129
250
  }
130
251
  queueLog(e, t, n) {
131
- this.loggerOptions?.isEnabled && this.pendingLogQueue.push({
252
+ this.loggerOptions?.isEnabled && (this.pendingLogQueue.push({
132
253
  type: e,
133
254
  name: t,
134
255
  detail: n
135
- });
256
+ }), this.batchDepth === 0 && this.flushLogs());
136
257
  }
137
258
  flushLogs() {
138
- if (!this.loggerOptions?.isEnabled || this.pendingLogQueue.length === 0) return;
139
- let e = typeof performance < "u" ? performance.now() : 0, t = this.pendingLogQueue;
140
- if (this.loggerOptions.filter) try {
141
- let e;
142
- if (this.loggerOptions.filter instanceof RegExp) e = this.loggerOptions.filter;
143
- else {
144
- let t = this.loggerOptions.filter.replace(/^\/|\/$/g, "");
145
- e = new RegExp(t);
146
- }
147
- t = t.filter((t) => e.test(t.name));
148
- } catch (e) {
149
- console.warn("[Logger Error]: Некорректный паттерн фильтрации логов", e);
150
- }
151
- if (t.length === 0) {
152
- this.pendingLogQueue = [];
153
- return;
154
- }
155
- let n = "", r = "", i = "color: #aaa; font-weight: normal;";
156
- if (this.loggerOptions.traceTime && e) {
157
- let t = performance.now() - e;
158
- if (n = ` | Duration: ${t.toFixed(3)} ms`, this.lastTransactionDuration !== null && this.lastTransactionDuration > 0) {
159
- let e = (t - this.lastTransactionDuration) / this.lastTransactionDuration * 100;
160
- e > .1 ? (r = ` 🔴 +${e.toFixed(1)}%`, i = "color: #e01e5a; font-weight: bold;") : e < -.1 ? (r = ` 🟢 ${e.toFixed(1)}%`, i = "color: #42b883; font-weight: bold;") : (r = " 🟢 stable", i = "color: #42b883; font-weight: bold;");
161
- } else r = " ⚪ first";
162
- this.lastTransactionDuration = t;
163
- }
164
- console.groupCollapsed(`%cREACTIVE TRANSACTION${this.loggerOptions.instanceName ? ` ${this.loggerOptions.instanceName}` : ""}%c Microtask Tick (Size: ${t.length}${n})%c${r}`, "background: #7952b3; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;", "color: #aaa; font-weight: normal;", i), t.forEach((e) => {
165
- this.log(e.type, e.name, e.detail);
166
- }), this.loggerOptions.traceTime && typeof performance < "u" && console.log(`%c[Execution Timestamp]: ${performance.now().toFixed(2)} ms`, "color: #7952b3; font-weight: bold;"), console.groupEnd(), this.pendingLogQueue = [];
259
+ !this.loggerOptions?.isEnabled || this.pendingLogQueue.length === 0 || (this.pendingLogQueue = []);
167
260
  }
168
- signal(e, t) {
169
- let n = this, r = e, i = /* @__PURE__ */ new Set(), a = typeof t == "string" ? { name: t } : t || {}, o = a.name || "unnamed_signal";
170
- return {
171
- get value() {
172
- if (n.activeEffect) {
173
- let e = n.activeEffect;
174
- i.has(e) || (i.add(e), e.cleanups.add(() => {
175
- i.delete(e);
176
- }));
261
+ resource(e, t, n) {
262
+ let r = n && typeof n == "object" ? n.name : n || "unnamed_resource", i = this.signal({
263
+ data: null,
264
+ loading: !0,
265
+ error: null,
266
+ isRetrying: !1
267
+ }, `resource:state:${r}`), a = this, o = null, s = async (t, n) => {
268
+ if (!n.aborted) {
269
+ a.untrack(() => {
270
+ i.value = {
271
+ data: i.value.data,
272
+ loading: !0,
273
+ error: null,
274
+ isRetrying: !1
275
+ };
276
+ });
277
+ try {
278
+ let r = await e(t, n);
279
+ n.aborted || a.untrack(() => {
280
+ i.value = {
281
+ data: r,
282
+ loading: !1,
283
+ error: null,
284
+ isRetrying: !1
285
+ };
286
+ });
287
+ } catch (e) {
288
+ n.aborted || a.untrack(() => {
289
+ i.value = {
290
+ data: null,
291
+ loading: !1,
292
+ error: e,
293
+ isRetrying: !1
294
+ };
295
+ });
177
296
  }
178
- return r;
297
+ }
298
+ };
299
+ return this.effect(() => {
300
+ let e = t ? t.value : void 0;
301
+ return o && o.abort(), o = new AbortController(), s(e, o.signal), () => {
302
+ o && o.abort();
303
+ };
304
+ }), {
305
+ get data() {
306
+ return i.value.data;
179
307
  },
180
- set value(e) {
181
- if (a?.validate && a.validate(e) !== !0) {
182
- let t = a.validate(e);
183
- console.error(`[ReactiveEngine] Validation failed for signal "${o}": ${typeof t == "string" ? t : "Unknown reason"}`, { value: e });
184
- return;
185
- }
186
- if ((e === null || typeof e != "object" && typeof e != "function") && r === e) return;
187
- let t = r;
188
- r = e, n.onSignalChange?.(o, e, t), i.forEach((e) => {
189
- e !== n.activeEffect && (n.isBatching ? n.pendingEffects.add(e) : (n.pendingEffects.add(e), n.isBatching || (n.isBatching = !0, queueMicrotask(() => {
190
- for (let e of n.pendingEffects) n.pendingEffects.delete(e), e.run();
191
- n.isBatching = !1, n.flushLogs?.();
192
- }))));
193
- });
308
+ get loading() {
309
+ return i.value.loading;
194
310
  },
195
- subscribe(e) {
196
- return n.effect(() => {
197
- e(this.value);
198
- }, `${n.frameworkPrefix}:use:${o}`);
199
- }
311
+ get error() {
312
+ return i.value.error;
313
+ },
314
+ get value() {
315
+ return i.value;
316
+ },
317
+ refetch: () => {
318
+ o && o.abort(), o = new AbortController(), s(t ? t.value : void 0, o.signal);
319
+ },
320
+ subscribe: (e) => i.subscribe(e)
200
321
  };
201
322
  }
323
+ }, n = class extends t {
324
+ isFlushScheduled = !1;
325
+ constructor(e) {
326
+ super(e), this.frameworkPrefix = "auto-core";
327
+ }
328
+ reactive(e, t = "reactive") {
329
+ let n = this;
330
+ Reflect.has(e, "__subscribe") || Object.defineProperty(e, "__subscribe", {
331
+ get: () => (e) => {
332
+ let t = !1;
333
+ return n.effect(() => {
334
+ try {
335
+ JSON.stringify(r);
336
+ } catch {
337
+ Object.values(r);
338
+ }
339
+ t || (t = !0, queueMicrotask(() => {
340
+ t = !1, e();
341
+ }));
342
+ }, "auto-framework-proxy-internal-subscription");
343
+ },
344
+ configurable: !0,
345
+ enumerable: !1
346
+ });
347
+ let r = super.reactive(e, t);
348
+ return r;
349
+ }
350
+ flushEffects() {
351
+ this.batchDepth > 0 || this.isFlushScheduled || (this.isFlushScheduled = !0, queueMicrotask(() => {
352
+ this.isFlushScheduled = !1, super.flushEffects();
353
+ }));
354
+ }
202
355
  effect(e, t) {
203
- let n = this, r = !0, i = {
356
+ let n = this, r = {
357
+ id: ++n.subscriberId,
204
358
  label: t,
205
359
  cleanups: /* @__PURE__ */ new Set(),
360
+ markDirty() {
361
+ n.pendingEffects.add(r), n.flushEffects();
362
+ },
206
363
  run() {
207
- let t = Array.from(this.cleanups);
208
- this.cleanups.clear(), t.forEach((e) => {
364
+ let t = Array.from(r.cleanups);
365
+ r.cleanups.clear(), t.forEach((e) => {
209
366
  try {
210
367
  e();
211
368
  } catch (e) {
212
- console.error("%c[Reactive Engine:Cleanup Error] %cОшибка в функции очистки (cleanup):", "color: white; background: red; padding: 2px 4px; border-radius: 3px;", "font-weight: bold;", e);
369
+ console.error("[Reactive Engine:Cleanup Error]", e);
213
370
  }
214
371
  });
215
- let i = n.activeEffect;
216
- n.activeEffect = this;
217
- let a = performance.now();
218
- n.safeRun(this, () => {
372
+ let i = n.activeConsumer;
373
+ n.activeConsumer = r;
374
+ try {
219
375
  let t = e();
220
- typeof t == "function" && this.cleanups.add(t);
221
- }), n.activeEffect = i;
222
- let o = performance.now() - a;
223
- if (!r && n.loggerOptions?.isEnabled) {
224
- let e = n.loggerOptions.filter;
225
- (!e || e instanceof RegExp && this.label && e.test(this.label)) && typeof n.queueLog == "function" && n.queueLog("effect", this.label || "unnamed-efect-0", {
226
- name: this.label || "unnamed-efect-0",
227
- type: "effect",
228
- detail: {
229
- status: "stable",
230
- duration: `${o.toFixed(3)}ms`,
231
- timestamp: a
232
- }
233
- });
376
+ typeof t == "function" && r.cleanups.add(t);
377
+ } finally {
378
+ n.activeConsumer = i;
234
379
  }
235
- r = !1;
236
380
  }
237
381
  };
238
- return this.allEffects.add(i), i.run(), () => {
239
- i.cleanups.forEach((e) => {
382
+ return n.allEffects.add(r), r.run(), () => {
383
+ Array.from(r.cleanups).forEach((e) => {
240
384
  try {
241
385
  e();
242
386
  } catch (e) {
243
- console.error("[Reactive Engine:Cleanup Error]", e);
387
+ console.error("[Reactive Engine:Dispose Cleanup Error]", e);
244
388
  }
245
- }), n.pendingEffects.delete(i), n.allEffects.delete(i);
389
+ }), r.cleanups.clear(), n.pendingEffects.delete(r), n.allEffects.delete(r);
246
390
  };
247
391
  }
248
- computedCache = /* @__PURE__ */ new Map();
249
- cleanupRegistry = new FinalizationRegistry((e) => {
250
- e();
251
- });
252
- computed(e, t) {
253
- if (this.computedCache.has(e)) {
254
- let t = this.computedCache.get(e)?.deref();
255
- if (t) return t;
256
- }
257
- let n = this, r = t || "unnamed_computed", i = this.signal(void 0, `[CORE_INTERNAL_SIGNAL=1]:${r}`), a = !0, o, s = this.effect(() => {
258
- o = e(), a = !1;
259
- let t = typeof performance < "u" && performance.now() ? "0.010ms" : "N/A";
260
- typeof n.queueLog == "function" && n.queueLog("computed", r, {
261
- value: o,
262
- duration: t
263
- }), i.value = o;
264
- }, `[CORE_INTERNAL_EFFECT=1]:${r}`), c = Array.from(this.allEffects)[this.allEffects.size - 1], l = () => {
265
- s(), c && n.allEffects.delete(c), n.computedCache.delete(e);
266
- }, u = {
267
- get value() {
268
- return a && (o = e(), a = !1, i.value = o), i.value;
269
- },
270
- subscribe: (e) => i.subscribe(e),
271
- destroy() {
272
- s(), l(), n.computedCache.delete(e);
392
+ }, r = class extends n {
393
+ autoLogQueue = [];
394
+ isHardFlushScheduled = !1;
395
+ constructor(e) {
396
+ let t = {
397
+ ...e,
398
+ logger: {
399
+ isEnabled: !0,
400
+ traceTime: !0,
401
+ isCoreOptimizationDebugEnabled: !0,
402
+ instanceName: e?.logger?.instanceName || "AUTOMATIC_HARD_CORE",
403
+ filter: e?.logger?.filter
273
404
  }
274
405
  };
275
- return this.cleanupRegistry.register(u, l), this.computedCache.set(e, new WeakRef(u)), u;
406
+ super(t), this.frameworkPrefix = "auto-hard-core";
276
407
  }
277
- reactive(e, t = "reactive") {
278
- if (this.proxyCache.has(e)) return this.proxyCache.get(e);
279
- let n = this, r = /* @__PURE__ */ new Map(), i = new Proxy(e, {
280
- get(e, i, a) {
281
- if (n.activeEffect) {
282
- let e = n.activeEffect;
283
- r.has(i) || r.set(i, /* @__PURE__ */ new Set());
284
- let t = r.get(i);
285
- t.has(e) || (t.add(e), e.cleanups.add(() => {
286
- t.delete(e);
287
- }));
288
- }
289
- if (Array.isArray(e) && typeof i == "string" && [
290
- "push",
291
- "pop",
292
- "shift",
293
- "unshift",
294
- "splice",
295
- "sort",
296
- "reverse"
297
- ].includes(i)) {
298
- let t = e[i];
299
- return function(...a) {
300
- let o = n.isBatching;
301
- n.isBatching = !0;
302
- let s = t.apply(e, a);
303
- return r.forEach((e, t) => {
304
- t !== i && Array.from(e).forEach((e) => {
305
- e !== n.activeEffect && n.pendingEffects.add(e);
306
- });
307
- }), n.isBatching = o, !n.isBatching && n.pendingEffects.size > 0 && (n.isBatching = !0, queueMicrotask(() => {
308
- for (let e of n.pendingEffects) n.pendingEffects.delete(e), e.run();
309
- n.isBatching = !1, n.flushLogs?.();
310
- })), s;
311
- };
312
- }
313
- let o = Reflect.get(e, i, a);
314
- return typeof o == "object" && o ? n.reactive(o, `${t}.${String(i)}`) : o;
315
- },
316
- set(e, i, a, o) {
317
- let s = Reflect.get(e, i, o);
318
- if (s === a) return !0;
319
- if (s !== a) {
320
- Reflect.set(e, i, a, o), n.onSignalChange?.(`${t}.${String(i)}`, a, s);
321
- let c = r.get(i), l = c ? Array.from(c) : [];
322
- if (Array.isArray(e)) {
323
- let e = r.get("length");
324
- e && l.push(...Array.from(e));
325
- }
326
- l.forEach((e) => {
327
- e !== n.activeEffect && (n.isBatching ? n.pendingEffects.add(e) : (n.pendingEffects.add(e), n.isBatching || (n.isBatching = !0, queueMicrotask(() => {
328
- for (let e of n.pendingEffects) n.pendingEffects.delete(e), e.run();
329
- n.isBatching = !1, n.flushLogs?.();
330
- }))));
331
- }), n.queueLog?.("reactive", `${t}.${String(i)}`, {
332
- action: "set",
333
- property: String(i),
334
- oldValue: s,
335
- newValue: a
336
- });
337
- }
338
- return !0;
339
- }
408
+ queueLog(e, t, n) {
409
+ this.autoLogQueue.push({
410
+ type: e,
411
+ name: t,
412
+ detail: n
340
413
  });
341
- return this.proxyCache.set(e, i), i;
342
414
  }
343
- batch(e) {
344
- e();
415
+ flushLogs() {
416
+ if (this.autoLogQueue.length === 0) return;
417
+ let e = {
418
+ signal: "background: #007acc; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;",
419
+ computed: "background: #42b883; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;",
420
+ effect: "background: #e01e5a; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;",
421
+ batch: "background: #7952b3; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;",
422
+ resource: "background: #d97706; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;",
423
+ reactive: "background: #007acc; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;"
424
+ };
425
+ console.groupCollapsed(`%cREACTIVE TRANSACTION [${this.frameworkPrefix.toUpperCase()}]%c Microtask Tick (Size: ${this.autoLogQueue.length})`, "background: #7952b3; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;", "color: #aaa; font-weight: normal;"), this.autoLogQueue.forEach((t) => {
426
+ let n = "";
427
+ if (t.type === "signal") {
428
+ let e = t.detail;
429
+ n = ` 🔄 Изменение: [${String(e.from)} -> ${String(e.to)}]`;
430
+ } else if (t.type === "computed") n = ` 🧮 Расчет кэша (${t.detail.duration})`;
431
+ else if (t.type === "effect") {
432
+ let e = t.detail;
433
+ n = e?.isTriggered ? ` ⚡️ Ререндер/Вызов (${e.duration || "0ms"})` : " 🟢 Инициализация подписки";
434
+ } else if (t.type === "resource") {
435
+ let e = t.detail;
436
+ n = e.loading ? " ⏳ ЗАГРУЗКА СЕТИ" : e.error ? " 🔴 ОШИБКА" : " 🟢 УСПЕШНО ОТВЕТИЛ";
437
+ }
438
+ console.groupCollapsed(`%c${t.type.toUpperCase()}%c [${t.name}]%c${n}`, e[t.type] || e.signal, "color: #aaa; font-weight: bold;", "color: #42b883; font-weight: bold;"), console.log("Детали операции:", t.detail), console.groupEnd();
439
+ }), console.groupEnd(), this.autoLogQueue = [];
345
440
  }
346
- delay(e, t) {
347
- return new Promise((n, r) => {
348
- if (t.aborted) return r(new DOMException("Aborted", "AbortError"));
349
- let i = setTimeout(() => {
350
- t.removeEventListener("abort", a), n();
351
- }, e), a = () => {
352
- clearTimeout(i), r(new DOMException("Aborted", "AbortError"));
353
- };
354
- t.addEventListener("abort", a, { once: !0 });
355
- });
441
+ flushEffects() {
442
+ this.batchDepth > 0 || this.isHardFlushScheduled || (this.isHardFlushScheduled = !0, queueMicrotask(() => {
443
+ this.isHardFlushScheduled = !1, this.flushLogs(), super.flushEffects();
444
+ }));
356
445
  }
357
- resource(t, n, r) {
358
- let i = r && typeof r == "object", a = i ? r.name : r || "unnamed_resource", o = i ? r : {}, s = o.resetDataOnSourceChange ?? !0, c = o.responseValidate, l = o.validateBeforeFetch, u = o.retryCount ?? 0, d = o.retryDelay ?? 1e3, f = o.isExponentialBackoffEnabled ?? !1, p = o.maxRetryDelay ?? 3e4, m = o.timeout, h = this.signal({
359
- data: null,
360
- loading: !0,
361
- error: null,
362
- isRetrying: !1
363
- }, `[CORE_INTERNAL_SIGNAL=1]:resource:state:${a}`), g = (e) => {
364
- h.value = e, typeof this.queueLog == "function" && this.queueLog("resource", a, {
365
- loading: e.loading,
366
- data: e.data,
367
- error: e.error,
368
- isRetrying: e.isRetrying
369
- });
370
- }, _ = async (n, r, i = !1) => {
371
- if (r.aborted) return;
372
- if (l) {
373
- let e = l(n);
374
- if (e === !1 || typeof e == "string") {
375
- if (r.aborted) return;
376
- let t = typeof e == "string" ? e : "Pre-fetch validation failed for resource", n = i ? null : this.untrack(() => h.value.data);
377
- g({
378
- data: n,
379
- loading: !1,
380
- error: Error(t),
381
- isRetrying: !1
382
- });
383
- return;
446
+ effect(e, t) {
447
+ let n = this, r = t || "unnamed_effect", i = !0;
448
+ n.queueLog("effect", r, {
449
+ isTriggered: !1,
450
+ phase: "mount"
451
+ });
452
+ let a = {
453
+ id: ++n.subscriberId,
454
+ label: r,
455
+ cleanups: /* @__PURE__ */ new Set(),
456
+ markDirty() {
457
+ n.pendingEffects.add(a), n.flushEffects();
458
+ },
459
+ run() {
460
+ let t = typeof performance < "u" ? performance.now() : 0, o = Array.from(a.cleanups);
461
+ a.cleanups.clear(), o.forEach((e) => {
462
+ try {
463
+ e();
464
+ } catch (e) {
465
+ console.error("[Reactive Engine:Cleanup Error]", e);
466
+ }
467
+ });
468
+ let s = n.activeConsumer;
469
+ n.activeConsumer = a;
470
+ try {
471
+ let t = e();
472
+ typeof t == "function" && a.cleanups.add(t);
473
+ } finally {
474
+ if (n.activeConsumer = s, !i && t && typeof n.queueLog == "function") {
475
+ let e = performance.now() - t;
476
+ n.queueLog("effect", r, {
477
+ isTriggered: !0,
478
+ phase: "update",
479
+ duration: `${e.toFixed(3)}ms`
480
+ });
481
+ }
482
+ i = !1;
384
483
  }
385
484
  }
386
- let o = i && s ? null : this.untrack(() => h.value.data);
387
- g({
388
- data: o,
485
+ };
486
+ return n.allEffects.add(a), a.run(), () => {
487
+ Array.from(a.cleanups).forEach((e) => {
488
+ try {
489
+ e();
490
+ } catch (e) {
491
+ console.error("[Reactive Engine:Dispose Cleanup Error]", e);
492
+ }
493
+ }), a.cleanups.clear(), n.pendingEffects.delete(a), n.allEffects.delete(a), n.queueLog("effect", r, { phase: "unmount" });
494
+ };
495
+ }
496
+ resource(e, t, n) {
497
+ let r = n && typeof n == "object" ? n.name : n || "unnamed_resource", i = this;
498
+ return super.resource(async (t, n) => {
499
+ i.queueLog("resource", r, {
389
500
  loading: !0,
390
501
  error: null,
391
- isRetrying: !1
502
+ data: null
392
503
  });
393
- for (let i = 0; i <= u; i++) {
394
- if (r.aborted) return;
395
- let o = r;
396
- try {
397
- if (m && m > 0) {
398
- let e = AbortSignal.timeout(m);
399
- o = AbortSignal.any([r, e]);
400
- }
401
- let e = await t(n, o);
402
- if (r.aborted) return;
403
- if (o.aborted) throw new DOMException("The operation timed out.", "TimeoutError");
404
- if (c) {
405
- let t = c(e);
406
- if (t === !1 || typeof t == "string") {
407
- if (r.aborted) return;
408
- g({
409
- data: null,
410
- loading: !1,
411
- error: Error(typeof t == "string" ? t : "Validation failed"),
412
- isRetrying: !1
413
- });
414
- return;
415
- }
416
- }
417
- if (r.aborted) return;
418
- g({
419
- data: e,
420
- loading: !1,
421
- error: null,
422
- isRetrying: !1
423
- });
424
- return;
425
- } catch (t) {
426
- if (r.aborted || t.name === "AbortError" && r.aborted) return;
427
- let n = t.name === "TimeoutError" || t.name === "AbortError" || t.message?.includes("timeout"), o = e({
428
- tested: [t.message],
429
- expectedKey: "THROW_CUSTOM_VALIDATION_ERROR_NO_RETRY",
430
- valueType: "number"
431
- })?.[0] === "1" || !1, s = o && e({
432
- tested: [t.message],
433
- expectedKey: "MESSAGE",
434
- valueType: "string"
435
- })?.[0] || "Custom validation error", c = o || t.name === "ValidationError";
436
- if (i === u || c) {
437
- if (r.aborted) return;
438
- let e = n ? Error(`Request timed out after ${m}ms`, { cause: t }) : o ? Error(s, { cause: t }) : t;
439
- g({
440
- data: null,
441
- loading: !1,
442
- error: e,
443
- isRetrying: !1
444
- });
445
- return;
446
- } else {
447
- if (r.aborted) return;
448
- let e = f ? d * 2 ** i : d;
449
- e = Math.min(e, p);
450
- let t = Math.random() * 200;
451
- e += t, g({
452
- data: h.value.data,
453
- loading: !0,
454
- error: null,
455
- isRetrying: !0
456
- }), console.warn(`[Resource Retry] "${a}" сбой по ${n ? "таймауту" : "ошибке сети"}. Попытка ${i + 1}/${u + 1}...`);
457
- try {
458
- if (await this.delay(e, r), r.aborted) return;
459
- } catch {
460
- return;
461
- }
462
- }
463
- }
504
+ try {
505
+ let a = await e(t, n);
506
+ return i.queueLog("resource", r, {
507
+ loading: !1,
508
+ error: null,
509
+ data: a
510
+ }), a;
511
+ } catch (e) {
512
+ throw i.queueLog("resource", r, {
513
+ loading: !1,
514
+ error: e,
515
+ data: null
516
+ }), e;
464
517
  }
465
- }, v = null;
466
- return this.effect(() => {
467
- let e = n ? n.value : void 0, t = new AbortController();
468
- return v = t, this.untrack(() => {
469
- _(e, t.signal, !0);
470
- }), () => t.abort();
471
- }, "[dev]"), {
472
- get data() {
473
- return h.value.data;
474
- },
475
- get loading() {
476
- return h.value.loading;
477
- },
478
- get error() {
479
- return h.value.error;
480
- },
481
- get isRetrying() {
482
- return h.value.isRetrying;
518
+ }, t, n);
519
+ }
520
+ reactive(e, t = "reactive") {
521
+ let n = this, r = super.reactive(e, t);
522
+ return new Proxy(r, {
523
+ get(e, r, i) {
524
+ let a = Reflect.get(e, r, i);
525
+ return typeof a == "object" && a ? n.reactive(a, `${t}.${String(r)}`) : a;
483
526
  },
527
+ set(e, r, i, a) {
528
+ let o = Reflect.get(e, r, a);
529
+ return o === i ? !0 : (n.queueLog("signal", `${t}.${String(r)}`, {
530
+ from: o,
531
+ to: i,
532
+ subscribersCount: 0,
533
+ subscribers: ["framework-reactive-proxy-subscriber"]
534
+ }), Reflect.set(e, r, i, a));
535
+ }
536
+ });
537
+ }
538
+ signal(e, t) {
539
+ let n = this, r = (typeof t == "string" ? { name: t } : t || {}).name || "unnamed_signal", i = super.signal(e, t);
540
+ return {
484
541
  get value() {
485
- return h.value;
542
+ return i.value;
486
543
  },
487
- refetch: () => {
488
- v?.abort(), v = new AbortController(), _(n ? n.value : void 0, v.signal, !1);
544
+ set value(e) {
545
+ let t = i.value;
546
+ if ((e === null || typeof e != "object" && typeof e != "function") && t === e) return;
547
+ let a = n.activeConsumer, o = a && "label" in a && typeof a.label == "string" ? a.label : "unnamed_effect";
548
+ n.queueLog("signal", r, {
549
+ from: t,
550
+ to: e,
551
+ subscribersCount: 0,
552
+ subscribers: [o]
553
+ }), i.value = e;
489
554
  },
490
- subscribe: (e) => h.subscribe(e)
555
+ subscribe(e) {
556
+ return i.subscribe(e);
557
+ }
491
558
  };
492
559
  }
493
- untrack(e) {
494
- let t = this.activeEffect;
495
- this.activeEffect = null;
496
- try {
497
- return e();
498
- } finally {
499
- this.activeEffect = t;
500
- }
501
- }
502
- safeRun(e, t) {
503
- try {
504
- t();
505
- } catch (e) {
506
- console.error("%c[Reactive Error] %cОшибка в эффекте/computed:", "color: white; background: red; padding: 2px 4px; border-radius: 3px;", "font-weight: bold;", e);
507
- }
560
+ computed(e, t) {
561
+ let n = this, r = t || "unnamed_computed", i = super.computed(e, t);
562
+ return {
563
+ get value() {
564
+ let e = typeof performance < "u" ? performance.now() : 0, t = i.value;
565
+ if (e) {
566
+ let i = performance.now() - e;
567
+ n.queueLog("computed", r, {
568
+ value: t,
569
+ duration: `${i.toFixed(3)}ms`
570
+ });
571
+ }
572
+ return t;
573
+ },
574
+ subscribe: (e) => i.subscribe(e),
575
+ destroy() {
576
+ i.destroy();
577
+ }
578
+ };
508
579
  }
509
580
  };
510
581
  //#endregion
511
- export { t as ReactiveEngine };
582
+ export { t as ReactiveEngine, n as ReactiveEngineAutomatic, r as ReactiveEngineAutomaticHard, e as ReactiveEngineCore };
512
583
 
513
584
  //# sourceMappingURL=core.mjs.map