@pravosleva/reactive-engine 2.5.0-alpha.5 → 2.5.0-alpha.7

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 +69 -66
  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 +90 -193
  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.7.umd.js +13 -0
  43. package/dist/reactive-engine@2.5.0-alpha.7.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.5.umd.js +0 -13
  53. package/dist/reactive-engine@2.5.0-alpha.5.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: (wasChanged: boolean, isAlreadyEpochShifted?: boolean) => {\n if (!hasBatchValue) return\n\n if (wasChanged) {\n if (!isAlreadyEpochShifted) {\n engine.epoch++\n }\n // ⚛️ КAНОНИЧЕСКИЙ БАТЧИНГ: Переводим в CHECK (1) вместо DIRTY (2).\n // Это блокирует веерные перезапуски сирот и алмазов на выходе из батча!\n notifySubscribers(1)\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,aAAc,EAAqB,IAAoC,CAChE,IAED,GACG,GACH,EAAO,QAIT,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, n) => {
69
+ c && (e ? (n || t.epoch++, d(1)) : 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: (wasChanged: boolean, isAlreadyEpochShifted?: boolean) => {\n if (!hasBatchValue) return\n\n if (wasChanged) {\n if (!isAlreadyEpochShifted) {\n engine.epoch++\n }\n // ⚛️ КAНОНИЧЕСКИЙ БАТЧИНГ: Переводим в CHECK (1) вместо DIRTY (2).\n // Это блокирует веерные перезапуски сирот и алмазов на выходе из батча!\n notifySubscribers(1)\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,GAAqB,MAAoC;GAChE,MAED,KACG,KACH,EAAO,SAIT,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,38 @@ 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) {
36
+ if (e._isScheduled) return;
37
+ e._isScheduled = !0;
82
38
  let t = e.depth || 0;
83
39
  this.pendingEffects[t] || (this.pendingEffects[t] = /* @__PURE__ */ new Set()), this.pendingEffects[t].add(e), t > this.maxPendingDepth && (this.maxPendingDepth = t);
84
40
  }
85
- queueLog(e, t, n) {
86
- u(e, t, n);
87
- }
88
41
  batch(e) {
89
- this.batchDepth++, this.batchIterationId ||= 0, this.batchIterationId++;
42
+ this.batchDepth++;
90
43
  try {
91
44
  return e();
92
45
  } finally {
93
46
  if (this.batchDepth--, this.batchDepth === 0) {
94
- if (this.batchedSignals.size > 0) {
95
- for (let e of this.batchedSignals) e._flushBatch && e._flushBatch();
47
+ if (this.batchIterationId ||= 0, this.batchIterationId++, this.batchedSignals.size > 0) {
48
+ let e = /* @__PURE__ */ new Map();
49
+ for (let t of this.batchedSignals) t._applyBatchValue && e.set(t, t._applyBatchValue());
50
+ this.epoch++;
51
+ let t = Array.from(this.batchedSignals);
96
52
  this.batchedSignals.clear();
53
+ for (let n of t) if (n._flushBatch) {
54
+ let t = e.get(n) ?? !1;
55
+ n._flushBatch(t, !0);
56
+ }
97
57
  }
98
- this.flushEffects(), this.batchComputedCache &&= (this.batchComputedCache.clear(), null);
58
+ this.flushEffects();
99
59
  }
100
60
  }
101
61
  }
@@ -108,7 +68,7 @@ var f = class {
108
68
  if (!t || t.size === 0) continue;
109
69
  let n = Array.from(t);
110
70
  t.clear();
111
- for (let e of n) if (!e.isDisposed && e.isDirty) {
71
+ for (let e of n) if (!e.isDisposed && (e._isScheduled = !1, e.isDirty)) {
112
72
  if (e.dependencies && e.dependencies.size > 0) {
113
73
  let t = !1;
114
74
  for (let n of e.dependencies) {
@@ -140,23 +100,20 @@ var f = class {
140
100
  this.activeConsumer = e;
141
101
  }
142
102
  }
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) {
103
+ signal(e, n) {
150
104
  return t(this, e, n);
151
105
  }
106
+ computed(t, n) {
107
+ return e(this, t, n);
108
+ }
152
109
  effect(e, t) {
153
- return a(this, e, t);
110
+ return i(this, e, t);
154
111
  }
155
112
  untrack(e) {
156
- return r(this, e);
113
+ return n(this, e);
157
114
  }
158
115
  reactive(e, t) {
159
- return i(this, e, t);
116
+ return r(this, e, t);
160
117
  }
161
118
  provide(e, t) {
162
119
  this.diRegistry.set(e, t), this.diCache.delete(e);
@@ -170,10 +127,6 @@ var f = class {
170
127
  if (this.diRegistry.has(e)) {
171
128
  let t = this.diRegistry.get(e);
172
129
  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
130
  let n = t.toString();
178
131
  if (!(n.startsWith("class ") || n.startsWith("class{") || t.prototype && t.prototype.constructor === t && !n.startsWith("function") && !n.includes("=>"))) {
179
132
  let n = t(this);
@@ -192,153 +145,97 @@ var f = class {
192
145
  this.cycleDetectionStack.delete(e);
193
146
  }
194
147
  }
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({
148
+ resource(e, t, n) {
149
+ 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
150
  data: null,
209
151
  loading: !0,
210
152
  error: null,
211
153
  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;
154
+ }, `[CORE_INTERNAL_SIGNAL=1]:resource:state:${i}`), u = async (t, n, r = !1) => {
155
+ if (!n.aborted) {
156
+ if (c) {
157
+ let e = c(t);
158
+ if (e === !1 || typeof e == "string") {
159
+ if (n.aborted) return;
160
+ let t = typeof e == "string" ? e : "Pre-fetch validation failed";
161
+ l.value = {
162
+ data: r ? null : l.value.data,
163
+ loading: !1,
164
+ error: t,
165
+ isRetrying: !1
166
+ };
167
+ return;
168
+ }
235
169
  }
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;
170
+ l.value = {
171
+ data: r && o ? null : l.value.data,
172
+ loading: !0,
173
+ error: null,
174
+ isRetrying: !1
175
+ };
247
176
  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({
177
+ let r = await e(t, n);
178
+ if (n.aborted) return;
179
+ if (s) {
180
+ let e = s(r);
181
+ if (e === !1 || typeof e == "string") {
182
+ l.value = {
256
183
  data: null,
257
184
  loading: !1,
258
- error: typeof t == "string" ? t : "Validation failed",
185
+ error: typeof e == "string" ? e : "Validation failed",
259
186
  isRetrying: !1
260
- });
187
+ };
261
188
  return;
262
189
  }
263
190
  }
264
- if (r.aborted) return;
265
- d({
266
- data: e,
191
+ l.value = {
192
+ data: r,
267
193
  loading: !1,
268
194
  error: null,
269
195
  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
- }
196
+ };
197
+ } catch (e) {
198
+ if (n.aborted) return;
199
+ l.value = {
200
+ data: null,
201
+ loading: !1,
202
+ error: e.message || "Fetch error",
203
+ isRetrying: !1
204
+ };
310
205
  }
311
206
  }
312
- }, p = null;
207
+ }, d = null;
313
208
  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"), {
209
+ let e = t ? t.value : void 0, n = new AbortController();
210
+ return d = n, this.untrack(() => {
211
+ u(e, n.signal, !0);
212
+ }), () => n.abort();
213
+ }), {
319
214
  get data() {
320
- return u.value.data;
215
+ return l.value.data;
321
216
  },
322
217
  get loading() {
323
- return u.value.loading;
218
+ return l.value.loading;
324
219
  },
325
220
  get error() {
326
- return u.value.error;
221
+ return l.value.error;
327
222
  },
328
223
  get isRetrying() {
329
- return u.value.isRetrying;
224
+ return l.value.isRetrying;
330
225
  },
331
226
  get value() {
332
- return u.value;
227
+ return l.value;
333
228
  },
334
229
  refetch: () => {
335
- p?.abort(), p = new AbortController(), f(n ? n.value : void 0, p.signal, !1);
230
+ d?.abort();
231
+ let e = new AbortController();
232
+ d = e, u(t ? t.value : void 0, e.signal, !1);
336
233
  },
337
- subscribe: (e) => u.subscribe(e)
234
+ subscribe: (e) => l.subscribe(e)
338
235
  };
339
236
  }
340
- };
237
+ }, o = class extends a {};
341
238
  //#endregion
342
- export { f as ReactiveEngine, f as ReactiveEngineAutomatic, f as ReactiveEngineCore, d as flushLogs, u as queueLog };
239
+ export { o as ReactiveEngineAutomatic, a as ReactiveEngineCore };
343
240
 
344
241
  //# sourceMappingURL=core.mjs.map