@pravosleva/reactive-engine 2.5.0-alpha.4 → 2.5.0-alpha.6

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 (53) hide show
  1. package/dist/angular/index.cjs +1 -1
  2. package/dist/angular/index.cjs.map +1 -1
  3. package/dist/angular/index.mjs +1 -1
  4. package/dist/core/core.d.ts +8 -16
  5. package/dist/core/core.d.ts.map +1 -1
  6. package/dist/core/core.method.computed.d.ts.map +1 -1
  7. package/dist/core/core.method.reactive.d.ts +0 -3
  8. package/dist/core/core.method.reactive.d.ts.map +1 -1
  9. package/dist/core/core.method.signal.d.ts.map +1 -1
  10. package/dist/core/index.d.ts +0 -1
  11. package/dist/core/index.d.ts.map +1 -1
  12. package/dist/core.automatic.cjs +1 -1
  13. package/dist/core.automatic.cjs.map +1 -1
  14. package/dist/core.automatic.mjs +1 -1
  15. package/dist/core.cjs +1 -1
  16. package/dist/core.cjs.map +1 -1
  17. package/dist/core.global.cjs +1 -1
  18. package/dist/core.global.cjs.map +1 -1
  19. package/dist/core.global.mjs +1 -1
  20. package/dist/core.method.computed.cjs +1 -1
  21. package/dist/core.method.computed.cjs.map +1 -1
  22. package/dist/core.method.computed.mjs +68 -69
  23. package/dist/core.method.computed.mjs.map +1 -1
  24. package/dist/core.method.reactive.cjs +1 -1
  25. package/dist/core.method.reactive.cjs.map +1 -1
  26. package/dist/core.method.reactive.mjs +104 -45
  27. package/dist/core.method.reactive.mjs.map +1 -1
  28. package/dist/core.method.signal.cjs +1 -1
  29. package/dist/core.method.signal.cjs.map +1 -1
  30. package/dist/core.method.signal.mjs +38 -64
  31. package/dist/core.method.signal.mjs.map +1 -1
  32. package/dist/core.mjs +86 -192
  33. package/dist/core.mjs.map +1 -1
  34. package/dist/decorators/withThrottleComputed/withThrottleComputed.d.ts +1 -1
  35. package/dist/index.cjs +1 -1
  36. package/dist/index.mjs +1 -1
  37. package/dist/index2.cjs +1 -1
  38. package/dist/index2.mjs +5 -5
  39. package/dist/react/index.cjs +1 -1
  40. package/dist/react/index.cjs.map +1 -1
  41. package/dist/react/index.mjs +1 -1
  42. package/dist/reactive-engine@2.5.0-alpha.6.umd.js +13 -0
  43. package/dist/reactive-engine@2.5.0-alpha.6.umd.js.map +1 -0
  44. package/dist/vue/index.cjs +1 -1
  45. package/dist/vue/index.cjs.map +1 -1
  46. package/dist/vue/index.mjs +1 -1
  47. package/package.json +1 -1
  48. package/dist/core.logger.cjs +0 -2
  49. package/dist/core.logger.cjs.map +0 -1
  50. package/dist/core.logger.mjs +0 -48
  51. package/dist/core.logger.mjs.map +0 -1
  52. package/dist/reactive-engine@2.5.0-alpha.4.umd.js +0 -13
  53. package/dist/reactive-engine@2.5.0-alpha.4.umd.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"core.method.signal.cjs","names":[],"sources":["../src/core/core.method.signal.ts"],"sourcesContent":["import { getExtractedValues } from '../utils/getExtractedValues'\nimport { Signal, SignalOptions } from './types'\n\nexport function createSignal<T>(\n engine: any,\n initialValue: T,\n optionsOrName?: SignalOptions<T> | string\n): Signal<T> {\n let value = initialValue\n let version = 0\n let name = typeof optionsOrName === 'string' ? optionsOrName : optionsOrName?.name\n const isInternalCoreSignal = !!name && getExtractedValues({\n tested: [name],\n expectedKey: 'CORE_INTERNAL_SIGNAL',\n valueType: 'number',\n })?.[0] === '1' || false\n const subscribers = new Set<any>()\n\n let hasBatchValue = false\n let batchInitialValue: T = initialValue\n\n const signalNode = {\n type: 'signal',\n get version() { return version },\n subscribers\n }\n\n const notifySubscribers = () => {\n // ⚡ ОПТИМИЗАЦИЯ: Прямой проход по Set через for...of (без Array.from)\n for (const sub of subscribers) {\n const rawSub = sub._node || sub\n if (rawSub.type === 'effect') {\n rawSub.isDirty = true\n engine.scheduleEffect(sub)\n } else if (rawSub.type === 'computed') {\n if (rawSub.markDirty) rawSub.markDirty(2)\n } else {\n if (typeof sub === 'function') {\n try { sub(value) } catch (err) { console.error(err) }\n } else if (sub && typeof sub.run === 'function') {\n try { sub.run() } catch (err) { console.error(err) }\n }\n }\n }\n }\n\n const signalInstance: Signal<T> = {\n get value() {\n const consumer = engine.activeConsumer\n if (consumer) {\n subscribers.add(engine.activeConsumer)\n engine.activeConsumer.dependencies.add(signalInstance)\n\n // Запоминаем маркер: этот сигнал активен в текущем расчете consumer-а\n if (consumer.activeRunId !== undefined) {\n (signalInstance as any)._lastSeenInRunId = consumer.activeRunId\n }\n }\n return value\n },\n\n set value(newValue: T) {\n const isObjectKick = value === newValue && value !== null && typeof value === 'object'\n if (Object.is(value, newValue) && !isObjectKick) return\n\n if (optionsOrName && typeof optionsOrName === 'object' && optionsOrName.validate) {\n const validation = optionsOrName.validate(newValue)\n if (validation !== true) {\n console.error(typeof validation === 'string' ? validation : '[Validation Error]')\n return\n }\n }\n\n if (engine.batchDepth > 0) {\n if (!hasBatchValue) {\n hasBatchValue = true\n batchInitialValue = value\n }\n value = newValue\n engine.batchedSignals.add(signalInstance)\n return\n }\n\n const oldValue = value\n value = newValue\n\n version++\n engine.epoch++\n\n engine.log({\n type: 'signal',\n label: name || 'signal',\n details: { from: oldValue, to: newValue },\n isInternalCoreSignal\n })\n\n notifySubscribers()\n if (engine.batchDepth === 0) engine.flushEffects()\n },\n\n get version() { return version },\n type: 'signal',\n\n subscribe(cb: (val: T) => void) {\n subscribers.add(cb)\n cb(value)\n return () => { subscribers.delete(cb) }\n },\n\n _flushBatch: () => {\n if (!hasBatchValue) return\n\n const wasChanged = !Object.is(batchInitialValue, value) || (value !== null && typeof value === 'object')\n\n if (wasChanged) {\n version++\n engine.epoch++\n\n engine.log({\n type: 'signal',\n label: name || 'signal_batched',\n details: { from: batchInitialValue, to: value },\n isInternalCoreSignal\n })\n\n // ⚡ ЗOЛОТOЙ МOСТ ТРАНЗАКЦИИ:\n // Вместо обычного notifySubscribers, принудительно переводим\n // всех прямых computed-подписчиков в боевой статус DIRTY (2)\n for (const sub of subscribers) {\n const rawSub = sub._node || sub\n if (rawSub.type === 'effect') {\n rawSub.isDirty = true\n engine.scheduleEffect(sub)\n } else if (rawSub.markDirty) {\n rawSub.markDirty(2) // 👈 Переводим в DIRTY (2), а не в CHECK (1)\n } else if (typeof sub === 'function') {\n try { sub(value) } catch (err) { console.error(err) }\n }\n }\n }\n\n hasBatchValue = false\n batchInitialValue = value\n },\n\n get hasBatchValue() { return hasBatchValue },\n } as any\n\n ;(signalInstance as any)._node = signalNode\n ;(signalInstance as any).subscribers = subscribers\n return signalInstance\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"core.method.signal.cjs","names":[],"sources":["../src/core/core.method.signal.ts"],"sourcesContent":["import { getExtractedValues } from '../utils/getExtractedValues'\nimport { Signal, SignalOptions } from './types'\n\nexport function createSignal<T>(\n engine: any,\n initialValue: T,\n optionsOrName?: SignalOptions<T> | string\n): Signal<T> {\n let value = initialValue\n let version = 0\n let name = typeof optionsOrName === 'string' ? optionsOrName : optionsOrName?.name\n\n const extracted = !!name ? getExtractedValues({\n tested: [name],\n expectedKey: 'CORE_INTERNAL_SIGNAL',\n valueType: 'number',\n })?.[0] : null\n const isInternalCoreSignal = extracted && extracted === '1'\n\n const subscribers = new Set<any>()\n\n let hasBatchValue = false\n let batchInitialValue: T = initialValue\n\n const signalNode = {\n type: 'signal',\n get version() { return version },\n subscribers\n }\n\n const notifySubscribers = (parentState: number = 2) => {\n for (const sub of subscribers) {\n const rawSub = sub._node || sub\n if (rawSub.type === 'effect') {\n rawSub.isDirty = true\n engine.scheduleEffect(sub)\n } else if (rawSub.type === 'computed') {\n if (rawSub.markDirty) rawSub.markDirty(parentState)\n } else {\n if (typeof sub === 'function') {\n try { sub(value) } catch (err) { console.error(err) }\n } else if (sub && typeof sub.run === 'function') {\n try { sub.run() } catch (err) { console.error(err) }\n }\n }\n }\n }\n\n const signalInstance: Signal<T> = {\n get value() {\n const consumer = engine.activeConsumer\n if (consumer) {\n subscribers.add(engine.activeConsumer)\n engine.activeConsumer.dependencies.add(signalInstance)\n\n const consumerRaw = consumer._node || consumer\n if (consumerRaw.depth !== undefined && consumerRaw.depth === 1) {\n consumerRaw.depth = 2\n }\n\n if (consumer.activeRunId !== undefined) {\n (signalInstance as any)._lastSeenInRunId = consumer.activeRunId\n }\n }\n return value\n },\n\n set value(newValue: T) {\n const isObjectKick = value === newValue && value !== null && typeof value === 'object'\n if (Object.is(value, newValue) && !isObjectKick) return\n\n if (optionsOrName && typeof optionsOrName === 'object' && optionsOrName.validate) {\n const validation = optionsOrName.validate(newValue)\n if (validation !== true) {\n console.error(typeof validation === 'string' ? validation : '[Validation Error]')\n return\n }\n }\n\n if (engine.batchDepth > 0) {\n if (!hasBatchValue) {\n hasBatchValue = true\n batchInitialValue = value\n }\n value = newValue\n\n ;(signalInstance as any).hasBatchValue = true\n notifySubscribers(1) // Мягкая маркировка CHECK (1) интра-ран чтений батча\n\n engine.batchedSignals.add(signalInstance)\n return\n }\n\n const oldValue = value\n value = newValue\n\n version++\n engine.epoch++\n\n notifySubscribers(2)\n if (engine.batchDepth === 0) engine.flushEffects()\n },\n\n get version() { return version },\n type: 'signal',\n\n subscribe(cb: (val: T) => void) {\n subscribers.add(cb)\n cb(value)\n return () => { subscribers.delete(cb) }\n },\n\n // ⚛️ ФАЗА 1: Чистая фиксация новых версий\n _applyBatchValue: () => {\n if (!hasBatchValue) return false\n const wasChanged = !Object.is(batchInitialValue, value) || (value !== null && typeof value === 'object')\n if (wasChanged) {\n version++\n return true\n }\n return false\n },\n\n // ⚛️ ФАЗА 2: Чистый атомарный push-уведомитель\n _flushBatch: (isAlreadyEpochShifted?: boolean) => {\n if (!hasBatchValue) return\n\n const wasChanged = !Object.is(batchInitialValue, value) || (value !== null && typeof value === 'object')\n\n if (wasChanged) {\n version++\n if (!isAlreadyEpochShifted) {\n engine.epoch++\n }\n // Возвращаем DIRTY (2) для канонического домино-эффекта\n notifySubscribers(2)\n } else {\n notifySubscribers(0)\n }\n\n hasBatchValue = false\n ;(signalInstance as any).hasBatchValue = false\n batchInitialValue = value\n }\n\n } as any\n\n ;(signalInstance as any)._node = signalNode\n ;(signalInstance as any).subscribers = subscribers\n return signalInstance\n}\n"],"mappings":"kDAGA,SAAgB,EACd,EACA,EACA,EACW,CACX,IAAI,EAAQ,EACR,EAAU,EACV,EAAO,OAAO,GAAkB,SAAW,EAAgB,GAAe,KAE5D,GAAS,EAAA,mBAAmB,CAC5C,OAAQ,CAAC,CAAI,EACb,YAAa,uBACb,UAAW,QACb,CAAC,CAAC,GAAG,GAGL,IAAM,EAAc,IAAI,IAEpB,EAAgB,GAChB,EAAuB,EAErB,EAAa,CACjB,KAAM,SACN,IAAI,SAAU,CAAE,OAAO,CAAQ,EAC/B,aACF,EAEM,GAAqB,EAAsB,IAAM,CACrD,IAAK,IAAM,KAAO,EAAa,CAC7B,IAAM,EAAS,EAAI,OAAS,EAC5B,GAAI,EAAO,OAAS,SAClB,EAAO,QAAU,GACjB,EAAO,eAAe,CAAG,OACpB,GAAI,EAAO,OAAS,WACrB,EAAO,WAAW,EAAO,UAAU,CAAW,OAElD,GAAI,OAAO,GAAQ,WACjB,GAAI,CAAE,EAAI,CAAK,CAAE,OAAS,EAAK,CAAE,QAAQ,MAAM,CAAG,CAAE,MAC/C,GAAI,GAAO,OAAO,EAAI,KAAQ,WACnC,GAAI,CAAE,EAAI,IAAI,CAAE,OAAS,EAAK,CAAE,QAAQ,MAAM,CAAG,CAAE,CAGzD,CACF,EAEM,EAA4B,CAChC,IAAI,OAAQ,CACV,IAAM,EAAW,EAAO,eACxB,GAAI,EAAU,CACZ,EAAY,IAAI,EAAO,cAAc,EACrC,EAAO,eAAe,aAAa,IAAI,CAAc,EAErD,IAAM,EAAc,EAAS,OAAS,EAClC,EAAY,QAAU,IAAA,IAAa,EAAY,QAAU,IAC3D,EAAY,MAAQ,GAGlB,EAAS,cAAgB,IAAA,KAC3B,EAAwB,iBAAmB,EAAS,YAExD,CACA,OAAO,CACT,EAEA,IAAI,MAAM,EAAa,CAEjB,YAAO,GAAG,EAAO,CAAQ,GAAK,EADb,IAAU,GAA8B,OAAO,GAAU,UAAnC,IAG3C,IAAI,GAAiB,OAAO,GAAkB,UAAY,EAAc,SAAU,CAChF,IAAM,EAAa,EAAc,SAAS,CAAQ,EAClD,GAAI,IAAe,GAAM,CACvB,QAAQ,MAAM,OAAO,GAAe,SAAW,EAAa,oBAAoB,EAChF,MACF,CACF,CAEA,GAAI,EAAO,WAAa,EAAG,CACpB,IACH,EAAgB,GAChB,EAAoB,GAEtB,EAAQ,EAEP,EAAwB,cAAgB,GACzC,EAAkB,CAAC,EAEnB,EAAO,eAAe,IAAI,CAAc,EACxC,MACF,CAGA,EAAQ,EAER,IACA,EAAO,QAEP,EAAkB,CAAC,EACf,EAAO,aAAe,GAAG,EAAO,aAAa,CAvBjD,CAwBF,EAEA,IAAI,SAAU,CAAE,OAAO,CAAQ,EAC/B,KAAM,SAEN,UAAU,EAAsB,CAG9B,OAFA,EAAY,IAAI,CAAE,EAClB,EAAG,CAAK,MACK,CAAE,EAAY,OAAO,CAAE,CAAE,CACxC,EAGA,qBACO,IACc,CAAC,OAAO,GAAG,EAAmB,CAAK,GAAwB,OAAO,GAAU,UAAnC,IAE1D,IACO,IAEF,GAIT,YAAc,GAAoC,CAC3C,IAEc,CAAC,OAAO,GAAG,EAAmB,CAAK,GAAwB,OAAO,GAAU,UAAnC,GAG1D,IACK,GACH,EAAO,QAGT,EAAkB,CAAC,GAEnB,EAAkB,CAAC,EAGrB,EAAgB,GACf,EAAwB,cAAgB,GACzC,EAAoB,EACtB,CAEF,EAIA,MAFC,GAAwB,MAAQ,EAChC,EAAwB,YAAc,EAChC,CACT"}
@@ -1,101 +1,75 @@
1
1
  import { getExtractedValues as e } from "./utils/getExtractedValues.mjs";
2
2
  //#region src/core/core.method.signal.ts
3
3
  function t(t, n, r) {
4
- let i = n, a = 0, o = typeof r == "string" ? r : r?.name, s = !!o && e({
4
+ let i = n, a = 0, o = typeof r == "string" ? r : r?.name;
5
+ o && e({
5
6
  tested: [o],
6
7
  expectedKey: "CORE_INTERNAL_SIGNAL",
7
8
  valueType: "number"
8
- })?.[0] === "1" || !1, c = /* @__PURE__ */ new Set(), l = !1, u = n, d = {
9
+ })?.[0];
10
+ let s = /* @__PURE__ */ new Set(), c = !1, l = n, u = {
9
11
  type: "signal",
10
12
  get version() {
11
13
  return a;
12
14
  },
13
- subscribers: c
14
- }, f = () => {
15
- for (let e of c) {
16
- let n = e._node || e;
17
- if (n.type === "effect") n.isDirty = !0, t.scheduleEffect(e);
18
- else if (n.type === "computed") n.markDirty && n.markDirty(2);
19
- else if (typeof e == "function") try {
20
- e(i);
15
+ subscribers: s
16
+ }, d = (e = 2) => {
17
+ for (let n of s) {
18
+ let r = n._node || n;
19
+ if (r.type === "effect") r.isDirty = !0, t.scheduleEffect(n);
20
+ else if (r.type === "computed") r.markDirty && r.markDirty(e);
21
+ else if (typeof n == "function") try {
22
+ n(i);
21
23
  } catch (e) {
22
24
  console.error(e);
23
25
  }
24
- else if (e && typeof e.run == "function") try {
25
- e.run();
26
+ else if (n && typeof n.run == "function") try {
27
+ n.run();
26
28
  } catch (e) {
27
29
  console.error(e);
28
30
  }
29
31
  }
30
- }, p = {
32
+ }, f = {
31
33
  get value() {
32
34
  let e = t.activeConsumer;
33
- return e && (c.add(t.activeConsumer), t.activeConsumer.dependencies.add(p), e.activeRunId !== void 0 && (p._lastSeenInRunId = e.activeRunId)), i;
35
+ if (e) {
36
+ s.add(t.activeConsumer), t.activeConsumer.dependencies.add(f);
37
+ let n = e._node || e;
38
+ n.depth !== void 0 && n.depth === 1 && (n.depth = 2), e.activeRunId !== void 0 && (f._lastSeenInRunId = e.activeRunId);
39
+ }
40
+ return i;
34
41
  },
35
42
  set value(e) {
36
- if (Object.is(i, e) && !(i === e && typeof i == "object" && i)) return;
37
- if (r && typeof r == "object" && r.validate) {
38
- let t = r.validate(e);
39
- if (t !== !0) {
40
- console.error(typeof t == "string" ? t : "[Validation Error]");
43
+ if (!(Object.is(i, e) && !(i === e && typeof i == "object" && i))) {
44
+ if (r && typeof r == "object" && r.validate) {
45
+ let t = r.validate(e);
46
+ if (t !== !0) {
47
+ console.error(typeof t == "string" ? t : "[Validation Error]");
48
+ return;
49
+ }
50
+ }
51
+ if (t.batchDepth > 0) {
52
+ c || (c = !0, l = i), i = e, f.hasBatchValue = !0, d(1), t.batchedSignals.add(f);
41
53
  return;
42
54
  }
55
+ i = e, a++, t.epoch++, d(2), t.batchDepth === 0 && t.flushEffects();
43
56
  }
44
- if (t.batchDepth > 0) {
45
- l || (l = !0, u = i), i = e, t.batchedSignals.add(p);
46
- return;
47
- }
48
- let n = i;
49
- i = e, a++, t.epoch++, t.log({
50
- type: "signal",
51
- label: o || "signal",
52
- details: {
53
- from: n,
54
- to: e
55
- },
56
- isInternalCoreSignal: s
57
- }), f(), t.batchDepth === 0 && t.flushEffects();
58
57
  },
59
58
  get version() {
60
59
  return a;
61
60
  },
62
61
  type: "signal",
63
62
  subscribe(e) {
64
- return c.add(e), e(i), () => {
65
- c.delete(e);
63
+ return s.add(e), e(i), () => {
64
+ s.delete(e);
66
65
  };
67
66
  },
68
- _flushBatch: () => {
69
- if (l) {
70
- if (!Object.is(u, i) || typeof i == "object" && i) {
71
- a++, t.epoch++, t.log({
72
- type: "signal",
73
- label: o || "signal_batched",
74
- details: {
75
- from: u,
76
- to: i
77
- },
78
- isInternalCoreSignal: s
79
- });
80
- for (let e of c) {
81
- let n = e._node || e;
82
- if (n.type === "effect") n.isDirty = !0, t.scheduleEffect(e);
83
- else if (n.markDirty) n.markDirty(2);
84
- else if (typeof e == "function") try {
85
- e(i);
86
- } catch (e) {
87
- console.error(e);
88
- }
89
- }
90
- }
91
- l = !1, u = i;
92
- }
93
- },
94
- get hasBatchValue() {
95
- return l;
67
+ _applyBatchValue: () => c && (!Object.is(l, i) || typeof i == "object" && i) ? (a++, !0) : !1,
68
+ _flushBatch: (e) => {
69
+ c && (!Object.is(l, i) || typeof i == "object" && i ? (a++, e || t.epoch++, d(2)) : d(0), c = !1, f.hasBatchValue = !1, l = i);
96
70
  }
97
71
  };
98
- return p._node = d, p.subscribers = c, p;
72
+ return f._node = u, f.subscribers = s, f;
99
73
  }
100
74
  //#endregion
101
75
  export { t as createSignal };
@@ -1 +1 @@
1
- {"version":3,"file":"core.method.signal.mjs","names":[],"sources":["../src/core/core.method.signal.ts"],"sourcesContent":["import { getExtractedValues } from '../utils/getExtractedValues'\nimport { Signal, SignalOptions } from './types'\n\nexport function createSignal<T>(\n engine: any,\n initialValue: T,\n optionsOrName?: SignalOptions<T> | string\n): Signal<T> {\n let value = initialValue\n let version = 0\n let name = typeof optionsOrName === 'string' ? optionsOrName : optionsOrName?.name\n const isInternalCoreSignal = !!name && getExtractedValues({\n tested: [name],\n expectedKey: 'CORE_INTERNAL_SIGNAL',\n valueType: 'number',\n })?.[0] === '1' || false\n const subscribers = new Set<any>()\n\n let hasBatchValue = false\n let batchInitialValue: T = initialValue\n\n const signalNode = {\n type: 'signal',\n get version() { return version },\n subscribers\n }\n\n const notifySubscribers = () => {\n // ⚡ ОПТИМИЗАЦИЯ: Прямой проход по Set через for...of (без Array.from)\n for (const sub of subscribers) {\n const rawSub = sub._node || sub\n if (rawSub.type === 'effect') {\n rawSub.isDirty = true\n engine.scheduleEffect(sub)\n } else if (rawSub.type === 'computed') {\n if (rawSub.markDirty) rawSub.markDirty(2)\n } else {\n if (typeof sub === 'function') {\n try { sub(value) } catch (err) { console.error(err) }\n } else if (sub && typeof sub.run === 'function') {\n try { sub.run() } catch (err) { console.error(err) }\n }\n }\n }\n }\n\n const signalInstance: Signal<T> = {\n get value() {\n const consumer = engine.activeConsumer\n if (consumer) {\n subscribers.add(engine.activeConsumer)\n engine.activeConsumer.dependencies.add(signalInstance)\n\n // Запоминаем маркер: этот сигнал активен в текущем расчете consumer-а\n if (consumer.activeRunId !== undefined) {\n (signalInstance as any)._lastSeenInRunId = consumer.activeRunId\n }\n }\n return value\n },\n\n set value(newValue: T) {\n const isObjectKick = value === newValue && value !== null && typeof value === 'object'\n if (Object.is(value, newValue) && !isObjectKick) return\n\n if (optionsOrName && typeof optionsOrName === 'object' && optionsOrName.validate) {\n const validation = optionsOrName.validate(newValue)\n if (validation !== true) {\n console.error(typeof validation === 'string' ? validation : '[Validation Error]')\n return\n }\n }\n\n if (engine.batchDepth > 0) {\n if (!hasBatchValue) {\n hasBatchValue = true\n batchInitialValue = value\n }\n value = newValue\n engine.batchedSignals.add(signalInstance)\n return\n }\n\n const oldValue = value\n value = newValue\n\n version++\n engine.epoch++\n\n engine.log({\n type: 'signal',\n label: name || 'signal',\n details: { from: oldValue, to: newValue },\n isInternalCoreSignal\n })\n\n notifySubscribers()\n if (engine.batchDepth === 0) engine.flushEffects()\n },\n\n get version() { return version },\n type: 'signal',\n\n subscribe(cb: (val: T) => void) {\n subscribers.add(cb)\n cb(value)\n return () => { subscribers.delete(cb) }\n },\n\n _flushBatch: () => {\n if (!hasBatchValue) return\n\n const wasChanged = !Object.is(batchInitialValue, value) || (value !== null && typeof value === 'object')\n\n if (wasChanged) {\n version++\n engine.epoch++\n\n engine.log({\n type: 'signal',\n label: name || 'signal_batched',\n details: { from: batchInitialValue, to: value },\n isInternalCoreSignal\n })\n\n // ⚡ ЗOЛОТOЙ МOСТ ТРАНЗАКЦИИ:\n // Вместо обычного notifySubscribers, принудительно переводим\n // всех прямых computed-подписчиков в боевой статус DIRTY (2)\n for (const sub of subscribers) {\n const rawSub = sub._node || sub\n if (rawSub.type === 'effect') {\n rawSub.isDirty = true\n engine.scheduleEffect(sub)\n } else if (rawSub.markDirty) {\n rawSub.markDirty(2) // 👈 Переводим в DIRTY (2), а не в CHECK (1)\n } else if (typeof sub === 'function') {\n try { sub(value) } catch (err) { console.error(err) }\n }\n }\n }\n\n hasBatchValue = false\n batchInitialValue = value\n },\n\n get hasBatchValue() { return hasBatchValue },\n } as any\n\n ;(signalInstance as any)._node = signalNode\n ;(signalInstance as any).subscribers = subscribers\n return signalInstance\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"core.method.signal.mjs","names":[],"sources":["../src/core/core.method.signal.ts"],"sourcesContent":["import { getExtractedValues } from '../utils/getExtractedValues'\nimport { Signal, SignalOptions } from './types'\n\nexport function createSignal<T>(\n engine: any,\n initialValue: T,\n optionsOrName?: SignalOptions<T> | string\n): Signal<T> {\n let value = initialValue\n let version = 0\n let name = typeof optionsOrName === 'string' ? optionsOrName : optionsOrName?.name\n\n const extracted = !!name ? getExtractedValues({\n tested: [name],\n expectedKey: 'CORE_INTERNAL_SIGNAL',\n valueType: 'number',\n })?.[0] : null\n const isInternalCoreSignal = extracted && extracted === '1'\n\n const subscribers = new Set<any>()\n\n let hasBatchValue = false\n let batchInitialValue: T = initialValue\n\n const signalNode = {\n type: 'signal',\n get version() { return version },\n subscribers\n }\n\n const notifySubscribers = (parentState: number = 2) => {\n for (const sub of subscribers) {\n const rawSub = sub._node || sub\n if (rawSub.type === 'effect') {\n rawSub.isDirty = true\n engine.scheduleEffect(sub)\n } else if (rawSub.type === 'computed') {\n if (rawSub.markDirty) rawSub.markDirty(parentState)\n } else {\n if (typeof sub === 'function') {\n try { sub(value) } catch (err) { console.error(err) }\n } else if (sub && typeof sub.run === 'function') {\n try { sub.run() } catch (err) { console.error(err) }\n }\n }\n }\n }\n\n const signalInstance: Signal<T> = {\n get value() {\n const consumer = engine.activeConsumer\n if (consumer) {\n subscribers.add(engine.activeConsumer)\n engine.activeConsumer.dependencies.add(signalInstance)\n\n const consumerRaw = consumer._node || consumer\n if (consumerRaw.depth !== undefined && consumerRaw.depth === 1) {\n consumerRaw.depth = 2\n }\n\n if (consumer.activeRunId !== undefined) {\n (signalInstance as any)._lastSeenInRunId = consumer.activeRunId\n }\n }\n return value\n },\n\n set value(newValue: T) {\n const isObjectKick = value === newValue && value !== null && typeof value === 'object'\n if (Object.is(value, newValue) && !isObjectKick) return\n\n if (optionsOrName && typeof optionsOrName === 'object' && optionsOrName.validate) {\n const validation = optionsOrName.validate(newValue)\n if (validation !== true) {\n console.error(typeof validation === 'string' ? validation : '[Validation Error]')\n return\n }\n }\n\n if (engine.batchDepth > 0) {\n if (!hasBatchValue) {\n hasBatchValue = true\n batchInitialValue = value\n }\n value = newValue\n\n ;(signalInstance as any).hasBatchValue = true\n notifySubscribers(1) // Мягкая маркировка CHECK (1) интра-ран чтений батча\n\n engine.batchedSignals.add(signalInstance)\n return\n }\n\n const oldValue = value\n value = newValue\n\n version++\n engine.epoch++\n\n notifySubscribers(2)\n if (engine.batchDepth === 0) engine.flushEffects()\n },\n\n get version() { return version },\n type: 'signal',\n\n subscribe(cb: (val: T) => void) {\n subscribers.add(cb)\n cb(value)\n return () => { subscribers.delete(cb) }\n },\n\n // ⚛️ ФАЗА 1: Чистая фиксация новых версий\n _applyBatchValue: () => {\n if (!hasBatchValue) return false\n const wasChanged = !Object.is(batchInitialValue, value) || (value !== null && typeof value === 'object')\n if (wasChanged) {\n version++\n return true\n }\n return false\n },\n\n // ⚛️ ФАЗА 2: Чистый атомарный push-уведомитель\n _flushBatch: (isAlreadyEpochShifted?: boolean) => {\n if (!hasBatchValue) return\n\n const wasChanged = !Object.is(batchInitialValue, value) || (value !== null && typeof value === 'object')\n\n if (wasChanged) {\n version++\n if (!isAlreadyEpochShifted) {\n engine.epoch++\n }\n // Возвращаем DIRTY (2) для канонического домино-эффекта\n notifySubscribers(2)\n } else {\n notifySubscribers(0)\n }\n\n hasBatchValue = false\n ;(signalInstance as any).hasBatchValue = false\n batchInitialValue = value\n }\n\n } as any\n\n ;(signalInstance as any)._node = signalNode\n ;(signalInstance as any).subscribers = subscribers\n return signalInstance\n}\n"],"mappings":";;AAGA,SAAgB,EACd,GACA,GACA,GACW;CACX,IAAI,IAAQ,GACR,IAAU,GACV,IAAO,OAAO,KAAkB,WAAW,IAAgB,GAAe;CAE5D,KAAS,EAAmB;EAC5C,QAAQ,CAAC,CAAI;EACb,aAAa;EACb,WAAW;CACb,CAAC,CAAC,GAAG;CAGL,IAAM,oBAAc,IAAI,IAAS,GAE7B,IAAgB,IAChB,IAAuB,GAErB,IAAa;EACjB,MAAM;EACN,IAAI,UAAU;GAAE,OAAO;EAAQ;EAC/B;CACF,GAEM,KAAqB,IAAsB,MAAM;EACrD,KAAK,IAAM,KAAO,GAAa;GAC7B,IAAM,IAAS,EAAI,SAAS;GAC5B,IAAI,EAAO,SAAS,UAElB,AADA,EAAO,UAAU,IACjB,EAAO,eAAe,CAAG;QACpB,IAAI,EAAO,SAAS,YACrB,EAAO,aAAW,EAAO,UAAU,CAAW;QAElD,IAAI,OAAO,KAAQ,YACjB,IAAI;IAAE,EAAI,CAAK;GAAE,SAAS,GAAK;IAAE,QAAQ,MAAM,CAAG;GAAE;QAC/C,IAAI,KAAO,OAAO,EAAI,OAAQ,YACnC,IAAI;IAAE,EAAI,IAAI;GAAE,SAAS,GAAK;IAAE,QAAQ,MAAM,CAAG;GAAE;EAGzD;CACF,GAEM,IAA4B;EAChC,IAAI,QAAQ;GACV,IAAM,IAAW,EAAO;GACxB,IAAI,GAAU;IAEZ,AADA,EAAY,IAAI,EAAO,cAAc,GACrC,EAAO,eAAe,aAAa,IAAI,CAAc;IAErD,IAAM,IAAc,EAAS,SAAS;IAKtC,AAJI,EAAY,UAAU,KAAA,KAAa,EAAY,UAAU,MAC3D,EAAY,QAAQ,IAGlB,EAAS,gBAAgB,KAAA,MAC3B,EAAwB,mBAAmB,EAAS;GAExD;GACA,OAAO;EACT;EAEA,IAAI,MAAM,GAAa;GAEjB,aAAO,GAAG,GAAO,CAAQ,KAAK,EADb,MAAU,KAA8B,OAAO,KAAU,YAAnC,KAG3C;QAAI,KAAiB,OAAO,KAAkB,YAAY,EAAc,UAAU;KAChF,IAAM,IAAa,EAAc,SAAS,CAAQ;KAClD,IAAI,MAAe,IAAM;MACvB,QAAQ,MAAM,OAAO,KAAe,WAAW,IAAa,oBAAoB;MAChF;KACF;IACF;IAEA,IAAI,EAAO,aAAa,GAAG;KAUzB,AATK,MACH,IAAgB,IAChB,IAAoB,IAEtB,IAAQ,GAEP,EAAwB,gBAAgB,IACzC,EAAkB,CAAC,GAEnB,EAAO,eAAe,IAAI,CAAc;KACxC;IACF;IASA,AANA,IAAQ,GAER,KACA,EAAO,SAEP,EAAkB,CAAC,GACf,EAAO,eAAe,KAAG,EAAO,aAAa;GAvBjD;EAwBF;EAEA,IAAI,UAAU;GAAE,OAAO;EAAQ;EAC/B,MAAM;EAEN,UAAU,GAAsB;GAG9B,OAFA,EAAY,IAAI,CAAE,GAClB,EAAG,CAAK,SACK;IAAE,EAAY,OAAO,CAAE;GAAE;EACxC;EAGA,wBACO,MACc,CAAC,OAAO,GAAG,GAAmB,CAAK,KAAwB,OAAO,KAAU,YAAnC,MAE1D,KACO,MAEF;EAIT,cAAc,MAAoC;GAC3C,MAEc,CAAC,OAAO,GAAG,GAAmB,CAAK,KAAwB,OAAO,KAAU,YAAnC,KAG1D,KACK,KACH,EAAO,SAGT,EAAkB,CAAC,KAEnB,EAAkB,CAAC,GAGrB,IAAgB,IACf,EAAwB,gBAAgB,IACzC,IAAoB;EACtB;CAEF;CAIA,OAFC,EAAwB,QAAQ,GAChC,EAAwB,cAAc,GAChC;AACT"}
package/dist/core.mjs CHANGED
@@ -1,59 +1,10 @@
1
- import { getExtractedValues as e } from "./utils/getExtractedValues.mjs";
2
- import { createComputed as t } from "./core.method.computed.mjs";
3
- import { createSignal as n } from "./core.method.signal.mjs";
4
- import { executeUntrack as r } from "./core.method.untrack.mjs";
5
- import { createReactive as i } from "./core.method.reactive.mjs";
6
- import { createEffect as a } from "./core.method.effect.mjs";
7
- import { ReactiveDebounceLogger as o } from "./core.logger.mjs";
1
+ import { createComputed as e } from "./core.method.computed.mjs";
2
+ import { createSignal as t } from "./core.method.signal.mjs";
3
+ import { executeUntrack as n } from "./core.method.untrack.mjs";
4
+ import { createReactive as r } from "./core.method.reactive.mjs";
5
+ import { createEffect as i } from "./core.method.effect.mjs";
8
6
  //#region src/core/core.ts
9
- var s = {
10
- signal: "background: #007acc; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;",
11
- computed: "background: #42b883; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;",
12
- effect: "background: #e01e5a; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;",
13
- batch: "background: #7952b3; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;",
14
- resource: "background: #d97706; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;",
15
- reactive: "background: #007acc; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;"
16
- }, c = null;
17
- function l(e) {
18
- if (e === null) return "null";
19
- if (e === void 0) return "undefined";
20
- if (typeof e == "object") try {
21
- return JSON.stringify(e);
22
- } catch {
23
- return "[Cyclic Object or Layer]";
24
- }
25
- return String(e);
26
- }
27
- function u(e, t, n) {
28
- c || (c = {
29
- id: Math.random().toString(36).substring(2, 9),
30
- pendingLogQueue: [],
31
- isFlushing: !1
32
- }, queueMicrotask(() => d())), c.pendingLogQueue.push({
33
- type: e,
34
- label: t,
35
- from: n?.from,
36
- to: n?.to,
37
- payload: n?.payload,
38
- timestamp: Date.now()
39
- });
40
- }
41
- function d() {
42
- if (!c || c.isFlushing) return;
43
- c.isFlushing = !0;
44
- let e = c.pendingLogQueue;
45
- if (e.length === 0) {
46
- c = null;
47
- return;
48
- }
49
- console.groupCollapsed(`%cREACTIVE TRANSACTION%c [id: ${c.id}] (${e.length} operations)`, "background: #7952b3; color: #fff; padding: 2px 6px; border-radius: 4px; font-weight: bold;", "color: #888; font-weight: normal;");
50
- for (let t of e) {
51
- let e = s[t.type], n = t.from !== void 0 || t.to !== void 0, r = `%c${t.type.toUpperCase()}%c ${t.label}`;
52
- n && (t.from ? r += ` ${l(t.from)} → ${l(t.to)}` : r += ` (${l(t.to)})`), t.payload === void 0 ? console.log(r, e, "color: inherit;") : (console.groupCollapsed(r, e, "color: inherit;"), console.log("Payload:", t.payload), console.groupEnd());
53
- }
54
- console.groupEnd(), c = null;
55
- }
56
- var f = class {
7
+ var a = class {
57
8
  frameworkPrefix = "core";
58
9
  logger;
59
10
  epoch = 0;
@@ -63,6 +14,7 @@ var f = class {
63
14
  pendingEffects = [];
64
15
  maxPendingDepth = 0;
65
16
  computedCache = /* @__PURE__ */ new WeakMap();
17
+ computedStringCache = /* @__PURE__ */ new Map();
66
18
  diRegistry = /* @__PURE__ */ new Map();
67
19
  diCache = /* @__PURE__ */ new Map();
68
20
  proxyCache = /* @__PURE__ */ new WeakMap();
@@ -72,30 +24,35 @@ var f = class {
72
24
  batchedSignals = /* @__PURE__ */ new Set();
73
25
  activeOwner = null;
74
26
  pendingCleanups = /* @__PURE__ */ new Set();
27
+ isLoggingEnabled = !1;
28
+ _poolArr = [];
75
29
  queueCleanup(e) {
76
30
  this.pendingCleanups.add(e);
77
31
  }
78
32
  constructor(e) {
79
- this.logger = e?.logger || { isEnabled: !1 };
33
+ this.logger = e?.logger || { isEnabled: !1 }, this.isLoggingEnabled = !!this.logger.isEnabled;
80
34
  }
81
35
  scheduleEffect(e) {
82
36
  let t = e.depth || 0;
83
37
  this.pendingEffects[t] || (this.pendingEffects[t] = /* @__PURE__ */ new Set()), this.pendingEffects[t].add(e), t > this.maxPendingDepth && (this.maxPendingDepth = t);
84
38
  }
85
- queueLog(e, t, n) {
86
- u(e, t, n);
87
- }
88
39
  batch(e) {
89
- this.batchDepth++, this.batchIterationId ||= 0, this.batchIterationId++;
40
+ this.batchDepth++;
90
41
  try {
91
42
  return e();
92
43
  } finally {
93
44
  if (this.batchDepth--, this.batchDepth === 0) {
94
- if (this.batchedSignals.size > 0) {
95
- for (let e of this.batchedSignals) e._flushBatch && e._flushBatch();
45
+ if (this.batchIterationId ||= 0, this.batchIterationId++, this.batchedSignals.size > 0) {
46
+ let e = /* @__PURE__ */ new Map();
47
+ for (let t of this.batchedSignals) t._applyBatchValue && e.set(t, t._applyBatchValue());
48
+ this.epoch++;
49
+ for (let t of this.batchedSignals) if (t._flushBatch) {
50
+ let n = e.get(t) ?? !1;
51
+ t._flushBatch(n, !0);
52
+ }
96
53
  this.batchedSignals.clear();
97
54
  }
98
- this.flushEffects(), this.batchComputedCache &&= (this.batchComputedCache.clear(), null);
55
+ this.flushEffects();
99
56
  }
100
57
  }
101
58
  }
@@ -140,23 +97,20 @@ var f = class {
140
97
  this.activeConsumer = e;
141
98
  }
142
99
  }
143
- log(e) {
144
- !this.logger || !this.logger.isEnabled || o.processLog(this.logger, u, e);
145
- }
146
- signal(e, t) {
147
- return n(this, e, t);
148
- }
149
- computed(e, n) {
100
+ signal(e, n) {
150
101
  return t(this, e, n);
151
102
  }
103
+ computed(t, n) {
104
+ return e(this, t, n);
105
+ }
152
106
  effect(e, t) {
153
- return a(this, e, t);
107
+ return i(this, e, t);
154
108
  }
155
109
  untrack(e) {
156
- return r(this, e);
110
+ return n(this, e);
157
111
  }
158
112
  reactive(e, t) {
159
- return i(this, e, t);
113
+ return r(this, e, t);
160
114
  }
161
115
  provide(e, t) {
162
116
  this.diRegistry.set(e, t), this.diCache.delete(e);
@@ -170,10 +124,6 @@ var f = class {
170
124
  if (this.diRegistry.has(e)) {
171
125
  let t = this.diRegistry.get(e);
172
126
  if (typeof t == "function") {
173
- if (t._isMockFunction) {
174
- let n = t(this);
175
- return n === void 0 ? t : (this.diCache.set(e, n), n);
176
- }
177
127
  let n = t.toString();
178
128
  if (!(n.startsWith("class ") || n.startsWith("class{") || t.prototype && t.prototype.constructor === t && !n.startsWith("function") && !n.includes("=>"))) {
179
129
  let n = t(this);
@@ -192,153 +142,97 @@ var f = class {
192
142
  this.cycleDetectionStack.delete(e);
193
143
  }
194
144
  }
195
- delay(e, t) {
196
- return new Promise((n, r) => {
197
- if (t.aborted) return r(new DOMException("Aborted", "AbortError"));
198
- let i = setTimeout(() => {
199
- t.removeEventListener("abort", a), n();
200
- }, e), a = () => {
201
- clearTimeout(i), r(new DOMException("Aborted", "AbortError"));
202
- };
203
- t.addEventListener("abort", a, { once: !0 });
204
- });
205
- }
206
- resource(t, n, r) {
207
- let i = r && typeof r == "object", a = i ? r.name || "unnamed_resource" : r || "unnamed_resource", o = i ? r : {}, s = o.resetDataOnSourceChange ?? !0, c = o.responseValidate, l = o.validateBeforeFetch, u = this.signal({
145
+ resource(e, t, n) {
146
+ let r = n && typeof n == "object", i = r ? n.name || "unnamed_resource" : n || "unnamed_resource", a = r ? n : {}, o = a.resetDataOnSourceChange ?? !0, s = a.responseValidate, c = a.validateBeforeFetch, l = this.signal({
208
147
  data: null,
209
148
  loading: !0,
210
149
  error: null,
211
150
  isRetrying: !1
212
- }, `[CORE_INTERNAL_SIGNAL=1]:resource:state:${a}`), d = (e) => {
213
- this.log({
214
- type: "resource",
215
- label: a,
216
- details: {
217
- to: e,
218
- from: u.value
219
- }
220
- }), u.value = e;
221
- }, f = async (n, r, i = !1) => {
222
- if (r.aborted) return;
223
- if (o.validateBeforeFetch && o.validateBeforeFetch(n), l) {
224
- let e = l(n);
225
- if (e === !1 || typeof e == "string") {
226
- if (r.aborted) return;
227
- let t = typeof e == "string" ? e : "Pre-fetch validation failed for resource", n = i ? null : this.untrack(() => u.value.data);
228
- d({
229
- data: n,
230
- loading: !1,
231
- error: t,
232
- isRetrying: !1
233
- });
234
- return;
151
+ }, `[CORE_INTERNAL_SIGNAL=1]:resource:state:${i}`), u = async (t, n, r = !1) => {
152
+ if (!n.aborted) {
153
+ if (c) {
154
+ let e = c(t);
155
+ if (e === !1 || typeof e == "string") {
156
+ if (n.aborted) return;
157
+ let t = typeof e == "string" ? e : "Pre-fetch validation failed";
158
+ l.value = {
159
+ data: r ? null : l.value.data,
160
+ loading: !1,
161
+ error: t,
162
+ isRetrying: !1
163
+ };
164
+ return;
165
+ }
235
166
  }
236
- }
237
- let f = i && s ? null : this.untrack(() => u.value.data);
238
- d({
239
- data: f,
240
- loading: !0,
241
- error: null,
242
- isRetrying: !1
243
- });
244
- for (let i = 0; i <= 0; i++) {
245
- if (r.aborted) return;
246
- let o = r;
167
+ l.value = {
168
+ data: r && o ? null : l.value.data,
169
+ loading: !0,
170
+ error: null,
171
+ isRetrying: !1
172
+ };
247
173
  try {
248
- let e = await t(n, o);
249
- if (r.aborted) return;
250
- if (o.aborted) throw new DOMException("The operation timed out.", "TimeoutError");
251
- if (c) {
252
- let t = c(e);
253
- if (t === !1 || typeof t == "string") {
254
- if (r.aborted) return;
255
- d({
174
+ let r = await e(t, n);
175
+ if (n.aborted) return;
176
+ if (s) {
177
+ let e = s(r);
178
+ if (e === !1 || typeof e == "string") {
179
+ l.value = {
256
180
  data: null,
257
181
  loading: !1,
258
- error: typeof t == "string" ? t : "Validation failed",
182
+ error: typeof e == "string" ? e : "Validation failed",
259
183
  isRetrying: !1
260
- });
184
+ };
261
185
  return;
262
186
  }
263
187
  }
264
- if (r.aborted) return;
265
- d({
266
- data: e,
188
+ l.value = {
189
+ data: r,
267
190
  loading: !1,
268
191
  error: null,
269
192
  isRetrying: !1
270
- });
271
- return;
272
- } catch (t) {
273
- if (r.aborted || t.name === "AbortError" && r.aborted) return;
274
- let n = t.name === "TimeoutError" || t.name === "AbortError" || t.message?.includes("timeout"), o = e({
275
- tested: [t.message],
276
- expectedKey: "THROW_CUSTOM_VALIDATION_ERROR_NO_RETRY",
277
- valueType: "number"
278
- })?.[0] === "1" || !1, s = o && e({
279
- tested: [t.message],
280
- expectedKey: "MESSAGE",
281
- valueType: "string"
282
- })?.[0] || "Custom validation error", c = o || t.name === "ValidationError";
283
- if (i === 0 || c) {
284
- if (r.aborted) return;
285
- let e = n ? Error("Request timed out after 1000ms", { cause: t }) : o ? Error(s, { cause: t }) : t;
286
- d({
287
- data: null,
288
- loading: !1,
289
- error: e instanceof Error ? e.message : typeof e == "string" ? e : `typeof finalError is ${typeof e}`,
290
- isRetrying: !1
291
- });
292
- return;
293
- } else {
294
- if (r.aborted) return;
295
- let e = 1e3 * 2 ** i;
296
- e = Math.min(e, 3e5);
297
- let t = Math.random() * 200;
298
- e += t, d({
299
- data: u.value.data,
300
- loading: !0,
301
- error: null,
302
- isRetrying: !0
303
- }), console.warn(`[Resource Retry] "${a}" сбой по ${n ? "таймауту" : "ошибке сети"}. Попытка ${i + 1}/${i + 1}...`);
304
- try {
305
- if (await this.delay(e, r), r.aborted) return;
306
- } catch {
307
- return;
308
- }
309
- }
193
+ };
194
+ } catch (e) {
195
+ if (n.aborted) return;
196
+ l.value = {
197
+ data: null,
198
+ loading: !1,
199
+ error: e.message || "Fetch error",
200
+ isRetrying: !1
201
+ };
310
202
  }
311
203
  }
312
- }, p = null;
204
+ }, d = null;
313
205
  return this.effect(() => {
314
- let e = n ? n.value : void 0, t = new AbortController();
315
- return p = t, this.untrack(() => {
316
- f(e, t.signal, !0);
317
- }), () => t.abort();
318
- }, "[CORE_INTERNAL_SIGNAL=1]:effect"), {
206
+ let e = t ? t.value : void 0, n = new AbortController();
207
+ return d = n, this.untrack(() => {
208
+ u(e, n.signal, !0);
209
+ }), () => n.abort();
210
+ }), {
319
211
  get data() {
320
- return u.value.data;
212
+ return l.value.data;
321
213
  },
322
214
  get loading() {
323
- return u.value.loading;
215
+ return l.value.loading;
324
216
  },
325
217
  get error() {
326
- return u.value.error;
218
+ return l.value.error;
327
219
  },
328
220
  get isRetrying() {
329
- return u.value.isRetrying;
221
+ return l.value.isRetrying;
330
222
  },
331
223
  get value() {
332
- return u.value;
224
+ return l.value;
333
225
  },
334
226
  refetch: () => {
335
- p?.abort(), p = new AbortController(), f(n ? n.value : void 0, p.signal, !1);
227
+ d?.abort();
228
+ let e = new AbortController();
229
+ d = e, u(t ? t.value : void 0, e.signal, !1);
336
230
  },
337
- subscribe: (e) => u.subscribe(e)
231
+ subscribe: (e) => l.subscribe(e)
338
232
  };
339
233
  }
340
- };
234
+ }, o = class extends a {};
341
235
  //#endregion
342
- export { f as ReactiveEngine, f as ReactiveEngineAutomatic, f as ReactiveEngineCore, d as flushLogs, u as queueLog };
236
+ export { o as ReactiveEngineAutomatic, a as ReactiveEngineCore };
343
237
 
344
238
  //# sourceMappingURL=core.mjs.map