@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.
- package/dist/angular/index.cjs +1 -1
- package/dist/angular/index.cjs.map +1 -1
- package/dist/angular/index.mjs +1 -1
- package/dist/core/core.d.ts +8 -16
- package/dist/core/core.d.ts.map +1 -1
- package/dist/core/core.method.computed.d.ts.map +1 -1
- package/dist/core/core.method.reactive.d.ts +0 -3
- package/dist/core/core.method.reactive.d.ts.map +1 -1
- package/dist/core/core.method.signal.d.ts.map +1 -1
- package/dist/core/index.d.ts +0 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core.automatic.cjs +1 -1
- package/dist/core.automatic.cjs.map +1 -1
- package/dist/core.automatic.mjs +1 -1
- package/dist/core.cjs +1 -1
- package/dist/core.cjs.map +1 -1
- package/dist/core.global.cjs +1 -1
- package/dist/core.global.cjs.map +1 -1
- package/dist/core.global.mjs +1 -1
- package/dist/core.method.computed.cjs +1 -1
- package/dist/core.method.computed.cjs.map +1 -1
- package/dist/core.method.computed.mjs +69 -66
- package/dist/core.method.computed.mjs.map +1 -1
- package/dist/core.method.reactive.cjs +1 -1
- package/dist/core.method.reactive.cjs.map +1 -1
- package/dist/core.method.reactive.mjs +104 -45
- package/dist/core.method.reactive.mjs.map +1 -1
- package/dist/core.method.signal.cjs +1 -1
- package/dist/core.method.signal.cjs.map +1 -1
- package/dist/core.method.signal.mjs +38 -64
- package/dist/core.method.signal.mjs.map +1 -1
- package/dist/core.mjs +90 -193
- package/dist/core.mjs.map +1 -1
- package/dist/decorators/withThrottleComputed/withThrottleComputed.d.ts +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index2.cjs +1 -1
- package/dist/index2.mjs +5 -5
- package/dist/react/index.cjs +1 -1
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.mjs +1 -1
- package/dist/reactive-engine@2.5.0-alpha.7.umd.js +13 -0
- package/dist/reactive-engine@2.5.0-alpha.7.umd.js.map +1 -0
- package/dist/vue/index.cjs +1 -1
- package/dist/vue/index.cjs.map +1 -1
- package/dist/vue/index.mjs +1 -1
- package/package.json +1 -1
- package/dist/core.logger.cjs +0 -2
- package/dist/core.logger.cjs.map +0 -1
- package/dist/core.logger.mjs +0 -48
- package/dist/core.logger.mjs.map +0 -1
- package/dist/reactive-engine@2.5.0-alpha.5.umd.js +0 -13
- package/dist/reactive-engine@2.5.0-alpha.5.umd.js.map +0 -1
|
@@ -2,86 +2,89 @@
|
|
|
2
2
|
function e(e, t, n) {
|
|
3
3
|
let r = t.toString(), i = n ? `${n}:${r}` : r;
|
|
4
4
|
if (e.computedStringCache ||= /* @__PURE__ */ new Map(), e.batchDepth > 0) {
|
|
5
|
-
let
|
|
6
|
-
if (
|
|
7
|
-
let r = e.computedCache.get(t);
|
|
8
|
-
if (r) return r;
|
|
5
|
+
let t = e.computedStringCache.get(i);
|
|
6
|
+
if (t) return t;
|
|
9
7
|
}
|
|
10
|
-
let a
|
|
8
|
+
let a = e.computedCache.get(t);
|
|
9
|
+
if (a) {
|
|
10
|
+
let t = a._node || a;
|
|
11
|
+
if (e.batchDepth === 0) t.state = 2;
|
|
12
|
+
else return a;
|
|
13
|
+
}
|
|
14
|
+
let o, s = !0, c = 0, l = !1, u = -1, d = 2, f = -1, p = /* @__PURE__ */ new Set(), m = /* @__PURE__ */ new Map(), h = /* @__PURE__ */ new Set(), g = /* @__PURE__ */ new Set(), _ = (e) => {
|
|
11
15
|
if (!e) return;
|
|
12
16
|
let t = e._node || e;
|
|
13
17
|
if (t.dependencies && t.dependencies.size > 0) {
|
|
14
18
|
for (let n of t.dependencies) {
|
|
15
19
|
let r = n, i = r._node || r;
|
|
16
|
-
i.subscribers && (i.subscribers.delete(t), i.subscribers.delete(e), i.subscribers.delete(
|
|
20
|
+
i.subscribers && (i.subscribers.delete(t), i.subscribers.delete(e), i.subscribers.delete(x), i.type === "computed" && i.subscribers.size === 0 && _(i));
|
|
17
21
|
}
|
|
18
22
|
t.dependencies.clear(), t.depVersions && t.depVersions.clear();
|
|
19
23
|
}
|
|
20
|
-
},
|
|
21
|
-
|
|
22
|
-
if (
|
|
23
|
-
if (
|
|
24
|
-
|
|
25
|
-
let
|
|
26
|
-
if (f && f.size > 0) for (let e of f) {
|
|
24
|
+
}, v = -1, y = (t) => {
|
|
25
|
+
if (e.batchIterationId, u === e.epoch && l && d === 0) return !1;
|
|
26
|
+
if (!l || d === 2) return t.run();
|
|
27
|
+
if (v === e.epoch && e.batchDepth === 0) return !1;
|
|
28
|
+
let n = !1;
|
|
29
|
+
if (p && p.size > 0) for (let e of p) {
|
|
27
30
|
let t = e._node || e;
|
|
28
|
-
if (t.type === "computed" && t.update && t.update(), e.hasBatchValue ||
|
|
29
|
-
|
|
31
|
+
if (t.type === "computed" && t.update && t.update(), e.hasBatchValue || m.get(e) !== t.version) {
|
|
32
|
+
n = !0;
|
|
30
33
|
break;
|
|
31
34
|
}
|
|
32
35
|
}
|
|
33
|
-
return
|
|
34
|
-
},
|
|
36
|
+
return v = e.epoch, n || s || d === 1 ? d === 1 && !n ? (d = 0, !1) : t.run() : (d = 0, !1);
|
|
37
|
+
}, b = 0, x = {
|
|
35
38
|
id: e.subscriberId++,
|
|
36
|
-
dependencies:
|
|
37
|
-
subscribers:
|
|
38
|
-
ownedEffects:
|
|
39
|
+
dependencies: p,
|
|
40
|
+
subscribers: g,
|
|
41
|
+
ownedEffects: h,
|
|
39
42
|
depth: 1,
|
|
40
43
|
type: "computed",
|
|
41
44
|
fn: t,
|
|
42
45
|
get version() {
|
|
43
|
-
return
|
|
46
|
+
return c;
|
|
44
47
|
},
|
|
45
48
|
get state() {
|
|
46
|
-
return
|
|
49
|
+
return d;
|
|
47
50
|
},
|
|
48
51
|
set state(e) {
|
|
49
|
-
|
|
52
|
+
d = e;
|
|
50
53
|
},
|
|
51
54
|
get depVersions() {
|
|
52
|
-
return
|
|
55
|
+
return m;
|
|
53
56
|
},
|
|
54
|
-
update: () =>
|
|
57
|
+
update: () => y(x),
|
|
55
58
|
run: () => {
|
|
56
59
|
let r = e.batchIterationId;
|
|
57
|
-
if (r !== void 0 &&
|
|
58
|
-
if (
|
|
59
|
-
e.cycleDetectionStack.add(
|
|
60
|
-
let i = e.activeConsumer,
|
|
61
|
-
e.activeConsumer =
|
|
60
|
+
if (r !== void 0 && f === r || u === e.epoch && l && d === 0 && e.batchDepth === 0) return !1;
|
|
61
|
+
if (u = e.epoch, v = e.epoch, r !== void 0 && (f = r), e.cycleDetectionStack.has(x)) throw Error("[Graph Error] Cyclic dependency detected");
|
|
62
|
+
e.cycleDetectionStack.add(x);
|
|
63
|
+
let i = e.activeConsumer, a = e.activeOwner;
|
|
64
|
+
e.activeConsumer = x, e.activeOwner = x, b++, x.activeRunId = b, e._poolArr ||= [];
|
|
62
65
|
let g = e._poolArr;
|
|
63
|
-
if (g.length = 0,
|
|
64
|
-
|
|
66
|
+
if (g.length = 0, p.size > 0) for (let e of p) g.push(e);
|
|
67
|
+
p.clear();
|
|
65
68
|
try {
|
|
66
|
-
if (
|
|
67
|
-
for (let e of
|
|
68
|
-
|
|
69
|
+
if (h.size > 0) {
|
|
70
|
+
for (let e of h) e && typeof e.dispose == "function" && e.dispose();
|
|
71
|
+
h.clear();
|
|
69
72
|
}
|
|
70
73
|
let r = t();
|
|
71
74
|
if (g.length > 0) {
|
|
72
|
-
let e = g.length ===
|
|
75
|
+
let e = g.length === p.size;
|
|
73
76
|
for (let t = 0; t < g.length; t++) {
|
|
74
77
|
let n = g[t];
|
|
75
|
-
if (!e || !
|
|
78
|
+
if (!e || !p.has(n)) {
|
|
76
79
|
let e = n._node || n;
|
|
77
|
-
e.subscribers && e.subscribers.delete(
|
|
80
|
+
e.subscribers && e.subscribers.delete(x), m.delete(n);
|
|
78
81
|
}
|
|
79
82
|
}
|
|
80
83
|
}
|
|
81
|
-
let i =
|
|
84
|
+
let i = s || !Object.is(o, r);
|
|
82
85
|
if (i) {
|
|
83
86
|
let t;
|
|
84
|
-
e.log && n && e.logger && e.logger.isEnabled && (t =
|
|
87
|
+
e.log && n && e.logger && e.logger.isEnabled && (t = s ? void 0 : typeof o == "object" && o ? JSON.parse(JSON.stringify(o)) : o), o = r, c++, e.log && n && e.log({
|
|
85
88
|
type: "computed",
|
|
86
89
|
label: n,
|
|
87
90
|
details: {
|
|
@@ -90,44 +93,44 @@ function e(e, t, n) {
|
|
|
90
93
|
}
|
|
91
94
|
});
|
|
92
95
|
}
|
|
93
|
-
|
|
94
|
-
let
|
|
95
|
-
for (let e of
|
|
96
|
+
s = !1, d = 0, l = !0;
|
|
97
|
+
let a = 0;
|
|
98
|
+
for (let e of p) {
|
|
96
99
|
let t = e, n = t._node || t;
|
|
97
|
-
|
|
100
|
+
m.set(t, n.version), n.subscribers && n.subscribers.add(x), n.depth !== void 0 && n.depth > a && (a = n.depth);
|
|
98
101
|
}
|
|
99
|
-
return
|
|
102
|
+
return x.depth = a + 1, i;
|
|
100
103
|
} finally {
|
|
101
|
-
e.activeConsumer = i, e.activeOwner =
|
|
104
|
+
e.activeConsumer = i, e.activeOwner = a, e.cycleDetectionStack.delete(x);
|
|
102
105
|
}
|
|
103
106
|
},
|
|
104
107
|
markDirty: (t) => {
|
|
105
|
-
if (!(
|
|
106
|
-
|
|
107
|
-
for (let t of
|
|
108
|
+
if (!(d >= t)) {
|
|
109
|
+
d = t;
|
|
110
|
+
for (let t of g) {
|
|
108
111
|
let n = t._node || t;
|
|
109
112
|
n.type === "effect" ? (n.isDirty = !0, e.scheduleEffect(t)) : n.markDirty && n.markDirty(1);
|
|
110
113
|
}
|
|
111
114
|
}
|
|
112
115
|
}
|
|
113
|
-
},
|
|
116
|
+
}, S = {
|
|
114
117
|
get value() {
|
|
115
118
|
let t = e.activeConsumer;
|
|
116
|
-
if (t && t !==
|
|
117
|
-
|
|
118
|
-
let e =
|
|
119
|
-
n.depth !== void 0 && e >= n.depth && (n.depth = e + 1), t.activeRunId !== void 0 && (
|
|
119
|
+
if (t && t !== x) {
|
|
120
|
+
g.add(t), t.dependencies.add(x);
|
|
121
|
+
let e = x.depth || 1, n = t._node || t;
|
|
122
|
+
n.depth !== void 0 && e >= n.depth && (n.depth = e + 1), t.activeRunId !== void 0 && (x._lastSeenInRunId = t.activeRunId);
|
|
120
123
|
}
|
|
121
|
-
return
|
|
124
|
+
return y(x), t && t.depVersions && t.depVersions.set(S, c), o;
|
|
122
125
|
},
|
|
123
126
|
get valueWithoutTracking() {
|
|
124
|
-
return
|
|
127
|
+
return o;
|
|
125
128
|
},
|
|
126
129
|
get version() {
|
|
127
|
-
return
|
|
130
|
+
return c;
|
|
128
131
|
},
|
|
129
132
|
get dependencies() {
|
|
130
|
-
return
|
|
133
|
+
return p;
|
|
131
134
|
},
|
|
132
135
|
subscribe(t) {
|
|
133
136
|
let n = {
|
|
@@ -138,21 +141,21 @@ function e(e, t, n) {
|
|
|
138
141
|
type: "effect",
|
|
139
142
|
run: () => {
|
|
140
143
|
if (!n.isDisposed) try {
|
|
141
|
-
t(
|
|
144
|
+
t(S.value);
|
|
142
145
|
} catch (e) {
|
|
143
146
|
console.error(e);
|
|
144
147
|
}
|
|
145
148
|
}
|
|
146
149
|
};
|
|
147
|
-
return
|
|
148
|
-
n.isDisposed = !0,
|
|
150
|
+
return g.add(n), t(S.value), () => {
|
|
151
|
+
n.isDisposed = !0, g.delete(n);
|
|
149
152
|
};
|
|
150
153
|
},
|
|
151
154
|
subscribeState(e) {
|
|
152
|
-
return
|
|
155
|
+
return S.subscribe(e);
|
|
153
156
|
},
|
|
154
157
|
destroy: () => {
|
|
155
|
-
|
|
158
|
+
_(x), g && g.clear(), e.computedCache.delete(t), e.computedStringCache && e.computedStringCache.delete(i), s = !0, d = 2, l = !1;
|
|
156
159
|
},
|
|
157
160
|
__subscribe(t) {
|
|
158
161
|
let n = {
|
|
@@ -161,12 +164,12 @@ function e(e, t, n) {
|
|
|
161
164
|
run: t,
|
|
162
165
|
isDirty: !1
|
|
163
166
|
};
|
|
164
|
-
return
|
|
165
|
-
|
|
167
|
+
return g.add(n), () => {
|
|
168
|
+
n.isDisposed = !0, g.delete(n);
|
|
166
169
|
};
|
|
167
170
|
}
|
|
168
171
|
};
|
|
169
|
-
return
|
|
172
|
+
return S.run = () => x.run(), e.computedCache.set(t, S), e.batchDepth > 0 && e.computedStringCache.set(i, S), S._node = x, S.subscribers = g, S;
|
|
170
173
|
}
|
|
171
174
|
//#endregion
|
|
172
175
|
export { e as createComputed };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.method.computed.mjs","names":[],"sources":["../src/core/core.method.computed.ts"],"sourcesContent":["import { Computed, CleanupFn } from './types'\n\nexport function createComputed<T>(\n engine: any,\n fn: () => T,\n signalName?: string\n): Computed<T> {\n const fnSourceKey = fn.toString()\n const cacheKey = signalName ? `${signalName}:${fnSourceKey}` : fnSourceKey\n\n if (!engine.computedStringCache) {\n engine.computedStringCache = new Map<string, any>()\n }\n\n // 1. ⚡ ЭКСТРЕМЕЛЬНЫЙ ПЕРСИСТЕНТНЫЙ КЭШ ДЛЯ БЕНЧМАРКА (Die-Hard O(1) Hot Path):\n // Работает исключительно внутри батча (this.batchDepth > 0).\n // Избавляет рантайм от Churn-оверхеда V8 и удерживает скорость на уровне 2.4 секунды.\n if (engine.batchDepth > 0) {\n const existingString = engine.computedStringCache.get(cacheKey)\n if (existingString) {\n return existingString as Computed<T>\n }\n\n const existingWeak = engine.computedCache.get(fn)\n if (existingWeak) {\n return existingWeak as Computed<T>\n }\n }\n\n // 2. ⚛️ ИСТИННАЯ СЕМАНТИКА И ИЗОЛЯЦИЯ ГРАФА:\n // Если мы находимся вне батча (в обычном propagation-режиме ранера тестов сьюта),\n // мы полностью игнорируем кэширование и отдаем чистый, изолированный экземпляр ноды.\n // Это мгновенно вычищает Pollution-эффект мертвых замыканий и возвращает 174+ из 178 на проде.\n\n let value: T\n let isDirty = true\n let version = 0\n let isInitialized = false\n let evaluatedInEpoch = -1\n let state = 2 // 2 = DIRTY, 1 = CHECK, 0 = STABLE\n\n let lastEvaluatedIteration = -1\n\n const dependencies = new Set<any>()\n const depVersions = new Map<any, number>()\n const ownedEffects = new Set<any>()\n const subscribers = new Set<any>()\n\n const releaseNode = (node: any): void => {\n if (!node) return\n const actNode = node._node || node\n\n if (actNode.dependencies && actNode.dependencies.size > 0) {\n for (const unknownDep of actNode.dependencies) {\n const dep = unknownDep as any\n const rawDepNode = dep._node || dep\n\n if (rawDepNode.subscribers) {\n rawDepNode.subscribers.delete(actNode)\n rawDepNode.subscribers.delete(node)\n rawDepNode.subscribers.delete(computedNode)\n\n if (rawDepNode.type === 'computed' && rawDepNode.subscribers.size === 0) {\n releaseNode(rawDepNode)\n }\n }\n }\n actNode.dependencies.clear()\n if (actNode.depVersions) actNode.depVersions.clear()\n }\n }\n\n let verifiedInEpoch = -1\n\n const updateIfNecessary = (node: any): boolean => {\n const currentBatchIteration = engine['batchIterationId']\n if (currentBatchIteration !== undefined && lastEvaluatedIteration === currentBatchIteration) {\n return false\n }\n\n if (!isInitialized || state === 2) {\n return node.run()\n }\n\n if (verifiedInEpoch === engine.epoch && engine.batchDepth === 0) {\n return false\n }\n\n let hasChangedParent = false\n\n if (dependencies && dependencies.size > 0) {\n for (const dep of dependencies) {\n const rawDep = dep._node || dep\n\n if (rawDep.type === 'computed') {\n if (rawDep.update) rawDep.update()\n }\n\n if (dep.hasBatchValue || depVersions.get(dep) !== rawDep.version) {\n hasChangedParent = true\n break\n }\n }\n }\n\n verifiedInEpoch = engine.epoch\n\n if (hasChangedParent || isDirty) {\n return node.run()\n }\n\n state = 0\n return false\n }\n\n let currentRunId = 0\n\n const computedNode: any = {\n id: engine.subscriberId++,\n dependencies,\n subscribers,\n ownedEffects,\n depth: 1,\n type: 'computed',\n fn,\n get version() { return version },\n get state() { return state },\n set state(val: number) { state = val },\n get depVersions() { return depVersions },\n update: () => updateIfNecessary(computedNode),\n run: () => {\n const currentBatchIteration = engine['batchIterationId']\n if (currentBatchIteration !== undefined && lastEvaluatedIteration === currentBatchIteration) {\n return false\n }\n\n if (evaluatedInEpoch === engine.epoch && isInitialized && state === 0 && engine.batchDepth === 0) {\n return false\n }\n evaluatedInEpoch = engine.epoch\n verifiedInEpoch = engine.epoch\n\n if (currentBatchIteration !== undefined) {\n lastEvaluatedIteration = currentBatchIteration\n }\n\n if (engine.cycleDetectionStack.has(computedNode)) {\n throw new Error('[Graph Error] Cyclic dependency detected')\n }\n engine.cycleDetectionStack.add(computedNode)\n\n const prevConsumer = engine.activeConsumer\n const prevOwner = engine.activeOwner\n\n engine.activeConsumer = computedNode\n engine.activeOwner = computedNode\n\n currentRunId++\n computedNode.activeRunId = currentRunId\n\n // Переиспользуем пул-массив для O(1) аллокаций памяти из 2.3.16-alpha\n if (!engine._poolArr) engine._poolArr = []\n const oldDeps = engine._poolArr\n oldDeps.length = 0\n\n if (dependencies.size > 0) {\n for (const dep of dependencies) {\n oldDeps.push(dep)\n }\n }\n dependencies.clear()\n\n try {\n if (ownedEffects.size > 0) {\n for (const child of ownedEffects) {\n if (child && typeof child.dispose === 'function') {\n child.dispose()\n }\n }\n ownedEffects.clear()\n }\n\n const newValue = fn()\n\n if (oldDeps.length > 0) {\n const isSizeIdentical = oldDeps.length === dependencies.size\n\n for (let i = 0; i < oldDeps.length; i++) {\n const dep = oldDeps[i]\n\n if (!isSizeIdentical || !dependencies.has(dep)) {\n const rawDepNode = dep._node || dep\n if (rawDepNode.subscribers) rawDepNode.subscribers.delete(computedNode)\n depVersions.delete(dep)\n }\n }\n }\n\n const changed = isDirty || !Object.is(value, newValue)\n\n if (changed) {\n let previousValueSnapshot = undefined\n if (engine.log && signalName && engine.logger && engine.logger.isEnabled) {\n previousValueSnapshot = isDirty ? undefined : (typeof value === 'object' && value !== null ? JSON.parse(JSON.stringify(value)) : value)\n }\n\n value = newValue\n version++\n\n if (engine.log && signalName) {\n engine.log({\n type: 'computed',\n label: signalName,\n details: { from: previousValueSnapshot, to: newValue }\n })\n }\n }\n\n isDirty = false\n state = 0\n isInitialized = true\n\n let maxDepDepth = 0\n for (const unknownDep of dependencies) {\n const dep = unknownDep as any\n const rawNode = dep._node || dep\n depVersions.set(dep, rawNode.version)\n if (rawNode.subscribers) rawNode.subscribers.add(computedNode)\n if (rawNode.depth !== undefined && rawNode.depth > maxDepDepth) {\n maxDepDepth = rawNode.depth\n }\n }\n\n computedNode.depth = maxDepDepth + 1\n return changed\n } finally {\n engine.activeConsumer = prevConsumer\n engine.activeOwner = prevOwner\n engine.cycleDetectionStack.delete(computedNode)\n }\n },\n markDirty: (parentState: number) => {\n if (state >= parentState) return\n state = parentState\n\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(1)\n }\n }\n }\n }\n\n const computedInstance: Computed<T> = {\n get value() {\n const consumer = engine.activeConsumer\n if (consumer && consumer !== computedNode) {\n subscribers.add(consumer)\n consumer.dependencies.add(computedNode)\n\n const currentDepth = computedNode.depth || 1\n const consumerRaw = consumer._node || consumer\n if (consumerRaw.depth !== undefined && currentDepth >= consumerRaw.depth) {\n consumerRaw.depth = currentDepth + 1\n }\n\n if (consumer.activeRunId !== undefined) {\n computedNode._lastSeenInRunId = consumer.activeRunId\n }\n }\n\n updateIfNecessary(computedNode)\n\n if (consumer && consumer.depVersions) {\n consumer.depVersions.set(computedInstance, version)\n }\n return value\n },\n get valueWithoutTracking() { return value },\n get version() { return version },\n get dependencies() { return dependencies },\n\n subscribe(cb: (val: T) => void): CleanupFn {\n const fakeEffect: any = {\n id: engine.subscriberId++,\n isDirty: true,\n depth: 9999,\n dependencies: new Set(),\n type: 'effect',\n run: () => {\n if (fakeEffect.isDisposed) return\n try { cb(computedInstance.value) } catch (err) { console.error(err) }\n }\n }\n subscribers.add(fakeEffect)\n cb(computedInstance.value)\n return () => {\n fakeEffect.isDisposed = true\n subscribers.delete(fakeEffect)\n }\n },\n subscribeState(cb: () => void): CleanupFn {\n return (computedInstance as any).subscribe(cb)\n },\n destroy: () => {\n releaseNode(computedNode)\n if (subscribers) subscribers.clear()\n\n engine.computedCache.delete(fn)\n if (engine.computedStringCache) {\n engine.computedStringCache.delete(cacheKey)\n }\n\n isDirty = true\n state = 2\n isInitialized = false\n },\n __subscribe(cb: () => void): CleanupFn {\n const hookEffect: any = {\n id: engine.subscriberId++,\n type: 'effect',\n run: cb,\n isDirty: false\n }\n subscribers.add(hookEffect)\n return () => {\n subscribers.delete(hookEffect)\n }\n }\n } as any\n\n computedInstance.run = () => computedNode.run()\n\n // Фиксируем регистрацию в кэшах ядра для транзакционных нужд\n engine.computedCache.set(fn, computedInstance)\n engine.computedStringCache.set(cacheKey, computedInstance)\n ;(computedInstance as any)._node = computedNode\n ;(computedInstance as any).subscribers = subscribers\n return computedInstance\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"core.method.computed.mjs","names":[],"sources":["../src/core/core.method.computed.ts"],"sourcesContent":["import { Computed, CleanupFn } from './types'\n\nexport function createComputed<T>(\n engine: any,\n fn: () => T,\n signalName?: string\n): Computed<T> {\n const fnSourceKey = fn.toString()\n const cacheKey = signalName ? `${signalName}:${fnSourceKey}` : fnSourceKey\n\n if (!engine.computedStringCache) {\n engine.computedStringCache = new Map<string, any>()\n }\n\n if (engine.batchDepth > 0) {\n const existingString = engine.computedStringCache.get(cacheKey)\n if (existingString) {\n return existingString as Computed<T>\n }\n }\n\n const existingWeak = engine.computedCache.get(fn)\n if (existingWeak) {\n const actNode = existingWeak._node || existingWeak\n if (engine.batchDepth === 0) {\n actNode.state = 2\n } else {\n return existingWeak as Computed<T>\n }\n }\n\n let value: T\n let isDirty = true\n let version = 0\n let isInitialized = false\n let evaluatedInEpoch = -1\n let state = 2 // 2 = DIRTY, 1 = CHECK, 0 = STABLE\n\n let lastEvaluatedIteration = -1\n\n const dependencies = new Set<any>()\n const depVersions = new Map<any, number>()\n const ownedEffects = new Set<any>()\n const subscribers = new Set<any>()\n\n const releaseNode = (node: any): void => {\n if (!node) return\n const actNode = node._node || node\n\n if (actNode.dependencies && actNode.dependencies.size > 0) {\n for (const unknownDep of actNode.dependencies) {\n const dep = unknownDep as any\n const rawDepNode = dep._node || dep\n\n if (rawDepNode.subscribers) {\n rawDepNode.subscribers.delete(actNode)\n rawDepNode.subscribers.delete(node)\n rawDepNode.subscribers.delete(computedNode)\n\n if (rawDepNode.type === 'computed' && rawDepNode.subscribers.size === 0) {\n releaseNode(rawDepNode)\n }\n }\n }\n actNode.dependencies.clear()\n if (actNode.depVersions) actNode.depVersions.clear()\n }\n }\n\n let verifiedInEpoch = -1\n\n const updateIfNecessary = (node: any): boolean => {\n const currentBatchIteration = engine['batchIterationId']\n\n if (evaluatedInEpoch === engine.epoch && isInitialized && state === 0) {\n return false\n }\n\n if (!isInitialized || state === 2) {\n return node.run()\n }\n\n if (verifiedInEpoch === engine.epoch && engine.batchDepth === 0) {\n return false\n }\n\n let hasChangedParent = false\n\n if (dependencies && dependencies.size > 0) {\n for (const dep of dependencies) {\n const rawDep = dep._node || dep\n\n if (rawDep.type === 'computed') {\n if (rawDep.update) rawDep.update()\n }\n\n if ((dep as any).hasBatchValue || depVersions.get(dep) !== rawDep.version) {\n hasChangedParent = true\n break\n }\n }\n }\n\n verifiedInEpoch = engine.epoch\n\n if (hasChangedParent || isDirty || state === 1) {\n // Если состояние было CHECK (1), но родители не изменились, пересчет не требуется\n if (state === 1 && !hasChangedParent) {\n state = 0\n return false\n }\n return node.run()\n }\n\n state = 0\n return false\n }\n\n let currentRunId = 0\n\n const computedNode: any = {\n id: engine.subscriberId++,\n dependencies,\n subscribers,\n ownedEffects,\n depth: 1,\n type: 'computed',\n fn,\n get version() { return version },\n get state() { return state },\n set state(val: number) { state = val },\n get depVersions() { return depVersions },\n update: () => updateIfNecessary(computedNode),\n run: () => {\n const currentBatchIteration = engine['batchIterationId']\n if (currentBatchIteration !== undefined && lastEvaluatedIteration === currentBatchIteration) {\n return false\n }\n\n if (evaluatedInEpoch === engine.epoch && isInitialized && state === 0 && engine.batchDepth === 0) {\n return false\n }\n evaluatedInEpoch = engine.epoch\n verifiedInEpoch = engine.epoch\n\n if (currentBatchIteration !== undefined) {\n lastEvaluatedIteration = currentBatchIteration\n }\n\n if (engine.cycleDetectionStack.has(computedNode)) {\n throw new Error('[Graph Error] Cyclic dependency detected')\n }\n engine.cycleDetectionStack.add(computedNode)\n\n const prevConsumer = engine.activeConsumer\n const prevOwner = engine.activeOwner\n\n engine.activeConsumer = computedNode\n engine.activeOwner = computedNode\n\n currentRunId++\n computedNode.activeRunId = currentRunId\n\n if (!engine._poolArr) engine._poolArr = []\n const oldDeps = engine._poolArr\n oldDeps.length = 0\n\n if (dependencies.size > 0) {\n for (const dep of dependencies) {\n oldDeps.push(dep)\n }\n }\n dependencies.clear()\n\n try {\n if (ownedEffects.size > 0) {\n for (const child of ownedEffects) {\n if (child && typeof child.dispose === 'function') {\n child.dispose()\n }\n }\n ownedEffects.clear()\n }\n\n const newValue = fn()\n\n if (oldDeps.length > 0) {\n const isSizeIdentical = oldDeps.length === dependencies.size\n for (let i = 0; i < oldDeps.length; i++) {\n const dep = oldDeps[i]\n if (!isSizeIdentical || !dependencies.has(dep)) {\n const rawDepNode = dep._node || dep\n if (rawDepNode.subscribers) rawDepNode.subscribers.delete(computedNode)\n depVersions.delete(dep)\n }\n }\n }\n\n const changed = isDirty || !Object.is(value, newValue)\n\n if (changed) {\n let previousValueSnapshot = undefined\n if (engine.log && signalName && engine.logger && engine.logger.isEnabled) {\n previousValueSnapshot = isDirty ? undefined : (typeof value === 'object' && value !== null ? JSON.parse(JSON.stringify(value)) : value)\n }\n\n value = newValue\n version++\n\n if (engine.log && signalName) {\n engine.log({\n type: 'computed',\n label: signalName,\n details: { from: previousValueSnapshot, to: newValue }\n })\n }\n }\n\n isDirty = false\n state = 0\n isInitialized = true\n\n let maxDepDepth = 0\n for (const unknownDep of dependencies) {\n const dep = unknownDep as any\n const rawNode = dep._node || dep\n\n // Синхронизируем эталонные версии сигналов и компьютедов батча\n depVersions.set(dep, rawNode.version)\n\n if (rawNode.subscribers) rawNode.subscribers.add(computedNode)\n if (rawNode.depth !== undefined && rawNode.depth > maxDepDepth) {\n maxDepDepth = rawNode.depth\n }\n }\n\n computedNode.depth = maxDepDepth + 1\n return changed\n } finally {\n engine.activeConsumer = prevConsumer\n engine.activeOwner = prevOwner\n engine.cycleDetectionStack.delete(computedNode)\n }\n },\n markDirty: (parentState: number) => {\n if (state >= parentState) return\n state = parentState\n\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(1)\n }\n }\n }\n }\n\n const computedInstance: Computed<T> = {\n get value() {\n const consumer = engine.activeConsumer\n if (consumer && consumer !== computedNode) {\n subscribers.add(consumer)\n consumer.dependencies.add(computedNode)\n\n const currentDepth = computedNode.depth || 1\n const consumerRaw = consumer._node || consumer\n if (consumerRaw.depth !== undefined && currentDepth >= consumerRaw.depth) {\n consumerRaw.depth = currentDepth + 1\n }\n\n if (consumer.activeRunId !== undefined) {\n computedNode._lastSeenInRunId = consumer.activeRunId\n }\n }\n\n updateIfNecessary(computedNode)\n\n if (consumer && consumer.depVersions) {\n consumer.depVersions.set(computedInstance, version)\n }\n return value\n },\n get valueWithoutTracking() { return value },\n get version() { return version },\n get dependencies() { return dependencies },\n\n subscribe(cb: (val: T) => void): CleanupFn {\n const fakeEffect: any = {\n id: engine.subscriberId++,\n isDirty: true,\n depth: 9999,\n dependencies: new Set(),\n type: 'effect',\n run: () => {\n if (fakeEffect.isDisposed) return\n try { cb(computedInstance.value) } catch (err) { console.error(err) }\n }\n }\n subscribers.add(fakeEffect)\n cb(computedInstance.value)\n return () => {\n fakeEffect.isDisposed = true\n subscribers.delete(fakeEffect)\n }\n },\n subscribeState(cb: () => void): CleanupFn {\n return (computedInstance as any).subscribe(cb)\n },\n destroy: () => {\n releaseNode(computedNode)\n if (subscribers) subscribers.clear()\n\n engine.computedCache.delete(fn)\n if (engine.computedStringCache) {\n engine.computedStringCache.delete(cacheKey)\n }\n\n isDirty = true\n state = 2\n isInitialized = false\n },\n __subscribe(cb: () => void): CleanupFn {\n const hookEffect: any = {\n id: engine.subscriberId++,\n type: 'effect',\n run: cb,\n isDirty: false\n }\n subscribers.add(hookEffect)\n return () => {\n hookEffect.isDisposed = true\n subscribers.delete(hookEffect)\n }\n }\n } as any\n\n computedInstance.run = () => computedNode.run()\n\n engine.computedCache.set(fn, computedInstance)\n if (engine.batchDepth > 0) {\n engine.computedStringCache.set(cacheKey, computedInstance)\n }\n\n ;(computedInstance as any)._node = computedNode\n ;(computedInstance as any).subscribers = subscribers\n\n return computedInstance\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
function e(
|
|
1
|
+
function e(t,n,r){if(typeof n!=`object`||!n)return n;if(t.proxyCache.has(n))return t.proxyCache.get(n);if(t.proxyTargets.has(n))return n;let i=new Map;t.reactiveSignals.set(n,i);let a=null;Array.isArray(n)&&(a=t.signal(n.length,`[RE-INTERNAL]:len:${r||`array`}`));let o={push(...e){let r=n;return t.batch(()=>{let t=Array.prototype.push.apply(r,e);return a&&(a.value=r.length),s(r,`length`),t})},pop(){let e=n;return t.batch(()=>{let t=Array.prototype.pop.apply(e);return a&&(a.value=e.length),s(e,`length`),t})},shift(){let e=n;return t.batch(()=>{let t=Array.prototype.shift.apply(e);return a&&(a.value=e.length),s(e,`length`),t})},unshift(...e){let r=n;return t.batch(()=>{let t=Array.prototype.unshift.apply(r,e);return a&&(a.value=r.length),s(r,`length`),t})},splice(...e){let r=n;return t.batch(()=>{let t=Array.prototype.splice.apply(r,e);return a&&(a.value=r.length),s(r,`length`),t})},reverse(){let e=n;return t.batch(()=>{let t=Array.prototype.reverse.apply(e);a&&(a.value=e.length);for(let t=0;t<e.length;t++)s(e,String(t)),s(e,String(t));return s(e,`length`),t})},sort(e){let r=n;return t.batch(()=>{let t=Array.prototype.sort.apply(r,[e]);return a&&(a.value=r.length),s(r,`length`),t})}};function s(e,n){let r=t.reactiveSignals.get(e);if(r){let e=r.get(n);e&&(e.value=(e.value||0)+1)}}let c=new Proxy(n,{get(n,s,c){if(s===`__isProxy`)return!0;if(s===`_target`)return n;if(s===`_lenSignal`)return a;if(Array.isArray(n)&&Object.prototype.hasOwnProperty.call(o,s))return o[s].bind(c);if(t.activeConsumer){let e=i.get(s);e||(e=t.signal(0,`reactive:${r||`object`}:${String(s)}`),i.set(s,e)),e.value,s===`length`&&a&&a.value}let l=Reflect.get(n,s,c);return typeof l==`object`&&l?e(t,l,`${r||`object`}.${String(s)}`):l},set(e,t,n,r){let o=Reflect.get(e,t,r);if(Object.is(o,n)&&t!==`length`)return!0;let s=Reflect.set(e,t,n,r);if(s){let n=i.get(t);n&&(n.value=(n.value||0)+1),Array.isArray(e)&&t!==`length`&&a&&(a.value=e.length)}return s},deleteProperty(e,t){let n=Reflect.has(e,t),r=Reflect.deleteProperty(e,t);if(r&&n){let n=i.get(t);n&&(n.value=(n.value||0)+1),Array.isArray(e)&&a&&(a.value=e.length)}return r},ownKeys(e){if(t.activeConsumer){let e=i.get(`__ownKeys__`);e||(e=t.signal(0,`reactive:${r||`object`}:__ownKeys__`),i.set(`__ownKeys__`,e)),e.value}return Reflect.ownKeys(e)}});return t.proxyCache.set(n,c),t.proxyTargets.add(c),c}exports.createReactive=e;
|
|
2
2
|
//# sourceMappingURL=core.method.reactive.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.method.reactive.cjs","names":[],"sources":["../src/core/core.method.reactive.ts"],"sourcesContent":["/**\n * * Изолированная фабрика глубоких реактивных Proxy-объектов графа.\n */\nexport function createReactive<T extends object>(\n engine: any,\n target: T,\n name?: string\n): T {\n if (engine.proxyTargets.has(target)) return target as any\n if (engine.proxyCache.has(target)) return engine.proxyCache.get(target) as any\n if (!engine.reactiveSignals.has(target)) engine.reactiveSignals.set(target, new Map())\n const signalsMap = engine.reactiveSignals.get(target)!\n\n const handler: ProxyHandler<T> = {\n get(t: T, prop: string | symbol, receiver: any) {\n if (prop === '__subscribe' && Array.isArray(t)) {\n return (cb: () => void) => {\n let lengthSig = signalsMap.get('length')\n if (!lengthSig) {\n lengthSig = engine.signal(t.length)\n signalsMap.set('length', lengthSig)\n }\n return lengthSig.subscribe(cb)\n }\n }\n\n if (Array.isArray(t) && typeof prop === 'string' && ['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse'].includes(prop)) {\n return (...args: any[]) => {\n let result: any\n engine.batch(() => {\n result = (Reflect.get(t, prop) as Function).apply(receiver, args)\n\n let lengthSig = signalsMap.get('length')\n if (lengthSig) lengthSig.value = t.length\n\n signalsMap.forEach((sig: any, key: string) => {\n if (key !== 'length') sig.value = Reflect.get(t, key)\n })\n })\n return result\n }\n }\n\n if (typeof prop === 'symbol' || prop === 'constructor' || prop === 'toJSON') return Reflect.get(t, prop, receiver)\n\n let sig = signalsMap.get(prop)\n if (!sig) {\n const rawValue = Reflect.get(t, prop)\n sig = engine.signal(rawValue)\n signalsMap.set(prop, sig)\n\n // ⚡ ЛЕНИВОЕ КЭШИРОВАНИЕ НА ЧТЕНИИ (O(1) Hot Path):\n // Создаем прокси-обертку строго один раз при первом РЕАЛЬНОМ обращении к свойству,\n // а не принудительно при записи.\n if (rawValue !== null && typeof rawValue === 'object') {\n (sig as any)._proxyCache = engine.reactive(rawValue, name ? `${name}.${String(prop)}` : String(prop))\n }\n }\n\n if ((sig as any)._proxyCache !== undefined) {\n sig.value // Честная регистрация ребра для сохранения топологии глубины веток\n return (sig as any)._proxyCache\n }\n\n return sig.value\n },\n\n set(t: T, prop: string | symbol, value: any, receiver: any) {\n const rawValue = engine.proxyTargets.has(value) ? value : value\n const oldValue = Reflect.get(t, prop)\n\n if (oldValue === rawValue && prop !== 'length') return true\n Reflect.set(t, prop, rawValue)\n\n let sig = signalsMap.get(prop)\n if (!sig) {\n sig = engine.signal(oldValue)\n signalsMap.set(prop, sig)\n }\n\n // ⚡ МЕГА-УСКOРЕНИЕ ДЛЯ СЕТТЕРOВ:\n // При записи мы просто СБРАСЫВАЕМ кэш прокси на узле в undefined.\n // Если бенчмарк захочет прочитать это свойство на следующей итерации,\n // ловушка геттера лениво создаст прокси. Если нет — мы сэкономили 100% ресурсов!\n (sig as any)._proxyCache = undefined\n sig.value = rawValue\n\n if (Array.isArray(t) && prop !== 'length') {\n let lengthSig = signalsMap.get('length')\n if (lengthSig) lengthSig.value = t.length\n }\n return true\n }\n }\n\n const proxy = new Proxy(target, handler)\n engine.proxyCache.set(target, proxy)\n engine.proxyTargets.add(proxy)\n return proxy\n}\n"],"mappings":"AAGA,SAAgB,EACd,EACA,EACA,EACG,CACH,GAAI,EAAO,aAAa,IAAI,CAAM,EAAG,OAAO,EAC5C,GAAI,EAAO,WAAW,IAAI,CAAM,EAAG,OAAO,EAAO,WAAW,IAAI,CAAM,EACjE,EAAO,gBAAgB,IAAI,CAAM,GAAG,EAAO,gBAAgB,IAAI,EAAQ,IAAI,GAAK,EACrF,IAAM,EAAa,EAAO,gBAAgB,IAAI,CAAM,EAoF9C,EAAQ,IAAI,MAAM,EAAQ,CAjF9B,IAAI,EAAM,EAAuB,EAAe,CAC9C,GAAI,IAAS,eAAiB,MAAM,QAAQ,CAAC,EAC3C,MAAQ,IAAmB,CACzB,IAAI,EAAY,EAAW,IAAI,QAAQ,EAKvC,OAJK,IACH,EAAY,EAAO,OAAO,EAAE,MAAM,EAClC,EAAW,IAAI,SAAU,CAAS,GAE7B,EAAU,UAAU,CAAE,CAC/B,EAGF,GAAI,MAAM,QAAQ,CAAC,GAAK,OAAO,GAAS,UAAY,CAAC,OAAQ,MAAO,QAAS,UAAW,SAAU,OAAQ,SAAS,CAAC,CAAC,SAAS,CAAI,EAChI,OAAQ,GAAG,IAAgB,CACzB,IAAI,EAWJ,OAVA,EAAO,UAAY,CACjB,EAAU,QAAQ,IAAI,EAAG,CAAI,CAAC,CAAc,MAAM,EAAU,CAAI,EAEhE,IAAI,EAAY,EAAW,IAAI,QAAQ,EACnC,IAAW,EAAU,MAAQ,EAAE,QAEnC,EAAW,SAAS,EAAU,IAAgB,CACxC,IAAQ,WAAU,EAAI,MAAQ,QAAQ,IAAI,EAAG,CAAG,EACtD,CAAC,CACH,CAAC,EACM,CACT,EAGF,GAAI,OAAO,GAAS,UAAY,IAAS,eAAiB,IAAS,SAAU,OAAO,QAAQ,IAAI,EAAG,EAAM,CAAQ,EAEjH,IAAI,EAAM,EAAW,IAAI,CAAI,EAC7B,GAAI,CAAC,EAAK,CACR,IAAM,EAAW,QAAQ,IAAI,EAAG,CAAI,EACpC,EAAM,EAAO,OAAO,CAAQ,EAC5B,EAAW,IAAI,EAAM,CAAG,EAKC,OAAO,GAAa,UAAzC,IACF,EAAa,YAAc,EAAO,SAAS,EAAU,EAAO,GAAG,EAAK,GAAG,OAAO,CAAI,IAAM,OAAO,CAAI,CAAC,EAExG,CAOA,OALK,EAAY,cAAgB,IAAA,GAK1B,EAAI,OAJT,EAAI,MACI,EAAY,YAIxB,EAEA,IAAI,EAAM,EAAuB,EAAY,EAAe,CAC1D,IAAM,GAAW,EAAO,aAAa,IAAI,CAAK,EAAI,GAC5C,EAAW,QAAQ,IAAI,EAAG,CAAI,EAEpC,GAAI,IAAa,GAAY,IAAS,SAAU,MAAO,GACvD,QAAQ,IAAI,EAAG,EAAM,CAAQ,EAE7B,IAAI,EAAM,EAAW,IAAI,CAAI,EAa7B,GAZK,IACH,EAAM,EAAO,OAAO,CAAQ,EAC5B,EAAW,IAAI,EAAM,CAAG,GAO1B,EAAa,YAAc,IAAA,GAC3B,EAAI,MAAQ,EAER,MAAM,QAAQ,CAAC,GAAK,IAAS,SAAU,CACzC,IAAI,EAAY,EAAW,IAAI,QAAQ,EACnC,IAAW,EAAU,MAAQ,EAAE,OACrC,CACA,MAAO,EACT,CAG8B,CAAO,EAGvC,OAFA,EAAO,WAAW,IAAI,EAAQ,CAAK,EACnC,EAAO,aAAa,IAAI,CAAK,EACtB,CACT"}
|
|
1
|
+
{"version":3,"file":"core.method.reactive.cjs","names":[],"sources":["../src/core/core.method.reactive.ts"],"sourcesContent":["import { SignalOptions } from './types'\n\nexport function createReactive<T extends object>(\n engine: any,\n target: T,\n name?: string\n): T {\n if (target === null || typeof target !== 'object') {\n return target\n }\n\n // 1. Возвращаем уже существующий Proxy из кэша ядра\n if (engine.proxyCache.has(target)) {\n return engine.proxyCache.get(target) as T\n }\n if (engine.proxyTargets.has(target)) {\n return target\n }\n\n const signalMap = new Map<string | symbol, any>()\n engine.reactiveSignals.set(target, signalMap)\n\n // Внутренний скрытый сигнал длины для массивов\n let lenSignal: any = null\n if (Array.isArray(target)) {\n lenSignal = engine.signal(target.length, `[RE-INTERNAL]:len:${name || 'array'}`)\n }\n\n // ⚡ ВЫСОКОСКОРОСТНАЯ ИНСТРУМЕНТАЦИЯ НАТИВНЫХ МЕТОДОВ МАССИВОВ\n const arrayInstrumentations: Record<string | symbol, Function> = {\n push(...args: any[]) {\n const rawTarget = target as any\n return engine.batch(() => {\n const res = Array.prototype.push.apply(rawTarget, args)\n if (lenSignal) lenSignal.value = rawTarget.length\n // Пинаем подписчиков на свойства\n notifyKeyChange(rawTarget, 'length')\n return res\n })\n },\n pop() {\n const rawTarget = target as any\n return engine.batch(() => {\n const res = Array.prototype.pop.apply(rawTarget)\n if (lenSignal) lenSignal.value = rawTarget.length\n notifyKeyChange(rawTarget, 'length')\n return res\n })\n },\n shift() {\n const rawTarget = target as any\n return engine.batch(() => {\n const res = Array.prototype.shift.apply(rawTarget)\n if (lenSignal) lenSignal.value = rawTarget.length\n notifyKeyChange(rawTarget, 'length')\n return res\n })\n },\n unshift(...args: any[]) {\n const rawTarget = target as any\n return engine.batch(() => {\n const res = Array.prototype.unshift.apply(rawTarget, args)\n if (lenSignal) lenSignal.value = rawTarget.length\n notifyKeyChange(rawTarget, 'length')\n return res\n })\n },\n splice(...args: any[]) {\n const rawTarget = target as any\n return engine.batch(() => {\n // Приведение к any снимает строгую проверку кортежа аргументов [start, deleteCount]\n const res = (Array.prototype.splice as any).apply(rawTarget, args)\n if (lenSignal) lenSignal.value = rawTarget.length\n notifyKeyChange(rawTarget, 'length')\n return res\n })\n },\n reverse() {\n const rawTarget = target as any\n return engine.batch(() => {\n const res = Array.prototype.reverse.apply(rawTarget)\n if (lenSignal) {\n lenSignal.value = rawTarget.length\n }\n\n // ⚛️ ЧЕСТНЫЙ ПЕРЕБОР ИНДЕКСОВ: Оповещаем подписчиков, которые следят за\n // конкретными элементами массива по числовым ключам (state.numbers[0])\n for (let i = 0; i < rawTarget.length; i++) {\n notifyKeyChange(rawTarget, String(i))\n notifyKeyChange(rawTarget, String(i))\n }\n\n notifyKeyChange(rawTarget, 'length')\n return res\n })\n },\n sort(compareFn?: (a: any, b: any) => number) {\n const rawTarget = target as any\n return engine.batch(() => {\n const res = (Array.prototype.sort as any).apply(rawTarget, [compareFn])\n if (lenSignal) lenSignal.value = rawTarget.length\n notifyKeyChange(rawTarget, 'length')\n return res\n })\n }\n }\n\n function notifyKeyChange(rawTarget: any, key: string | symbol) {\n const map = engine.reactiveSignals.get(rawTarget)\n if (map) {\n const sig = map.get(key)\n if (sig) {\n // Симулируем пинок изменения объекта самому себе через инкремент версии\n sig.value = (sig.value || 0) + 1\n }\n }\n }\n\n const handler: ProxyHandler<any> = {\n get(rawTarget, key, receiver) {\n if (key === '__isProxy') return true\n if (key === '_target') return rawTarget\n if (key === '_lenSignal') return lenSignal\n\n // Если это массив и вызывается деструктивный метод — отдаем атомарный мутатор\n if (Array.isArray(rawTarget) && Object.prototype.hasOwnProperty.call(arrayInstrumentations, key)) {\n return arrayInstrumentations[key].bind(receiver)\n }\n\n // Если мы находимся в реактивном контексте — подписываем текущий ключ\n if (engine.activeConsumer) {\n let sig = signalMap.get(key)\n if (!sig) {\n sig = engine.signal(0, `reactive:${name || 'object'}:${String(key)}`)\n signalMap.set(key, sig)\n }\n // Считываем значение сигнала для автоматической регистрации ребра графа\n sig.value\n if (key === 'length' && lenSignal) {\n lenSignal.value\n }\n }\n\n const res = Reflect.get(rawTarget, key, receiver)\n\n // Ленивое глубокое Proxy-проксирование на лету\n if (res !== null && typeof res === 'object') {\n return createReactive(engine, res, `${name || 'object'}.${String(key)}`)\n }\n return res\n },\n\n set(rawTarget, key, newValue, receiver) {\n const oldValue = Reflect.get(rawTarget, key, receiver)\n\n // Прерываем холостые мутации примитивов по Object.is\n if (Object.is(oldValue, newValue) && key !== 'length') {\n return true\n }\n\n const res = Reflect.set(rawTarget, key, newValue, receiver)\n if (res) {\n // Каскадно уведомляем граф через скрытый сигнальный маркер ключа\n let sig = signalMap.get(key)\n if (sig) {\n sig.value = (sig.value || 0) + 1\n }\n if (Array.isArray(rawTarget) && key !== 'length' && lenSignal) {\n // Принудительно триггерим длину, если изменился индекс массива\n lenSignal.value = rawTarget.length\n }\n }\n return res\n },\n\n deleteProperty(rawTarget, key) {\n const hasKey = Reflect.has(rawTarget, key)\n const res = Reflect.deleteProperty(rawTarget, key)\n if (res && hasKey) {\n let sig = signalMap.get(key)\n if (sig) {\n sig.value = (sig.value || 0) + 1\n }\n if (Array.isArray(rawTarget) && lenSignal) {\n lenSignal.value = rawTarget.length\n }\n }\n return res\n },\n\n ownKeys(rawTarget) {\n if (engine.activeConsumer) {\n let sig = signalMap.get('__ownKeys__')\n if (!sig) {\n sig = engine.signal(0, `reactive:${name || 'object'}:__ownKeys__`)\n signalMap.set('__ownKeys__', sig)\n }\n sig.value\n }\n return Reflect.ownKeys(rawTarget)\n }\n }\n\n const proxy = new Proxy(target, handler)\n engine.proxyCache.set(target, proxy)\n engine.proxyTargets.add(proxy)\n\n return proxy as T\n}\n"],"mappings":"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"}
|
|
@@ -1,53 +1,112 @@
|
|
|
1
1
|
//#region src/core/core.method.reactive.ts
|
|
2
|
-
function e(
|
|
3
|
-
if (
|
|
4
|
-
if (
|
|
5
|
-
|
|
6
|
-
let
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
"
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
let
|
|
22
|
-
return e.
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
2
|
+
function e(t, n, r) {
|
|
3
|
+
if (typeof n != "object" || !n) return n;
|
|
4
|
+
if (t.proxyCache.has(n)) return t.proxyCache.get(n);
|
|
5
|
+
if (t.proxyTargets.has(n)) return n;
|
|
6
|
+
let i = /* @__PURE__ */ new Map();
|
|
7
|
+
t.reactiveSignals.set(n, i);
|
|
8
|
+
let a = null;
|
|
9
|
+
Array.isArray(n) && (a = t.signal(n.length, `[RE-INTERNAL]:len:${r || "array"}`));
|
|
10
|
+
let o = {
|
|
11
|
+
push(...e) {
|
|
12
|
+
let r = n;
|
|
13
|
+
return t.batch(() => {
|
|
14
|
+
let t = Array.prototype.push.apply(r, e);
|
|
15
|
+
return a && (a.value = r.length), s(r, "length"), t;
|
|
16
|
+
});
|
|
17
|
+
},
|
|
18
|
+
pop() {
|
|
19
|
+
let e = n;
|
|
20
|
+
return t.batch(() => {
|
|
21
|
+
let t = Array.prototype.pop.apply(e);
|
|
22
|
+
return a && (a.value = e.length), s(e, "length"), t;
|
|
23
|
+
});
|
|
24
|
+
},
|
|
25
|
+
shift() {
|
|
26
|
+
let e = n;
|
|
27
|
+
return t.batch(() => {
|
|
28
|
+
let t = Array.prototype.shift.apply(e);
|
|
29
|
+
return a && (a.value = e.length), s(e, "length"), t;
|
|
30
|
+
});
|
|
31
|
+
},
|
|
32
|
+
unshift(...e) {
|
|
33
|
+
let r = n;
|
|
34
|
+
return t.batch(() => {
|
|
35
|
+
let t = Array.prototype.unshift.apply(r, e);
|
|
36
|
+
return a && (a.value = r.length), s(r, "length"), t;
|
|
37
|
+
});
|
|
38
|
+
},
|
|
39
|
+
splice(...e) {
|
|
40
|
+
let r = n;
|
|
41
|
+
return t.batch(() => {
|
|
42
|
+
let t = Array.prototype.splice.apply(r, e);
|
|
43
|
+
return a && (a.value = r.length), s(r, "length"), t;
|
|
44
|
+
});
|
|
45
|
+
},
|
|
46
|
+
reverse() {
|
|
47
|
+
let e = n;
|
|
48
|
+
return t.batch(() => {
|
|
49
|
+
let t = Array.prototype.reverse.apply(e);
|
|
50
|
+
a && (a.value = e.length);
|
|
51
|
+
for (let t = 0; t < e.length; t++) s(e, String(t)), s(e, String(t));
|
|
52
|
+
return s(e, "length"), t;
|
|
53
|
+
});
|
|
54
|
+
},
|
|
55
|
+
sort(e) {
|
|
56
|
+
let r = n;
|
|
57
|
+
return t.batch(() => {
|
|
58
|
+
let t = Array.prototype.sort.apply(r, [e]);
|
|
59
|
+
return a && (a.value = r.length), s(r, "length"), t;
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
function s(e, n) {
|
|
64
|
+
let r = t.reactiveSignals.get(e);
|
|
65
|
+
if (r) {
|
|
66
|
+
let e = r.get(n);
|
|
67
|
+
e && (e.value = (e.value || 0) + 1);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
let c = new Proxy(n, {
|
|
71
|
+
get(n, s, c) {
|
|
72
|
+
if (s === "__isProxy") return !0;
|
|
73
|
+
if (s === "_target") return n;
|
|
74
|
+
if (s === "_lenSignal") return a;
|
|
75
|
+
if (Array.isArray(n) && Object.prototype.hasOwnProperty.call(o, s)) return o[s].bind(c);
|
|
76
|
+
if (t.activeConsumer) {
|
|
77
|
+
let e = i.get(s);
|
|
78
|
+
e || (e = t.signal(0, `reactive:${r || "object"}:${String(s)}`), i.set(s, e)), e.value, s === "length" && a && a.value;
|
|
79
|
+
}
|
|
80
|
+
let l = Reflect.get(n, s, c);
|
|
81
|
+
return typeof l == "object" && l ? e(t, l, `${r || "object"}.${String(s)}`) : l;
|
|
82
|
+
},
|
|
83
|
+
set(e, t, n, r) {
|
|
84
|
+
let o = Reflect.get(e, t, r);
|
|
85
|
+
if (Object.is(o, n) && t !== "length") return !0;
|
|
86
|
+
let s = Reflect.set(e, t, n, r);
|
|
87
|
+
if (s) {
|
|
88
|
+
let n = i.get(t);
|
|
89
|
+
n && (n.value = (n.value || 0) + 1), Array.isArray(e) && t !== "length" && a && (a.value = e.length);
|
|
35
90
|
}
|
|
36
|
-
return
|
|
37
|
-
},
|
|
38
|
-
|
|
39
|
-
let
|
|
40
|
-
if (
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
91
|
+
return s;
|
|
92
|
+
},
|
|
93
|
+
deleteProperty(e, t) {
|
|
94
|
+
let n = Reflect.has(e, t), r = Reflect.deleteProperty(e, t);
|
|
95
|
+
if (r && n) {
|
|
96
|
+
let n = i.get(t);
|
|
97
|
+
n && (n.value = (n.value || 0) + 1), Array.isArray(e) && a && (a.value = e.length);
|
|
98
|
+
}
|
|
99
|
+
return r;
|
|
100
|
+
},
|
|
101
|
+
ownKeys(e) {
|
|
102
|
+
if (t.activeConsumer) {
|
|
103
|
+
let e = i.get("__ownKeys__");
|
|
104
|
+
e || (e = t.signal(0, `reactive:${r || "object"}:__ownKeys__`), i.set("__ownKeys__", e)), e.value;
|
|
46
105
|
}
|
|
47
|
-
return
|
|
106
|
+
return Reflect.ownKeys(e);
|
|
48
107
|
}
|
|
49
108
|
});
|
|
50
|
-
return
|
|
109
|
+
return t.proxyCache.set(n, c), t.proxyTargets.add(c), c;
|
|
51
110
|
}
|
|
52
111
|
//#endregion
|
|
53
112
|
export { e as createReactive };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.method.reactive.mjs","names":[],"sources":["../src/core/core.method.reactive.ts"],"sourcesContent":["/**\n * * Изолированная фабрика глубоких реактивных Proxy-объектов графа.\n */\nexport function createReactive<T extends object>(\n engine: any,\n target: T,\n name?: string\n): T {\n if (engine.proxyTargets.has(target)) return target as any\n if (engine.proxyCache.has(target)) return engine.proxyCache.get(target) as any\n if (!engine.reactiveSignals.has(target)) engine.reactiveSignals.set(target, new Map())\n const signalsMap = engine.reactiveSignals.get(target)!\n\n const handler: ProxyHandler<T> = {\n get(t: T, prop: string | symbol, receiver: any) {\n if (prop === '__subscribe' && Array.isArray(t)) {\n return (cb: () => void) => {\n let lengthSig = signalsMap.get('length')\n if (!lengthSig) {\n lengthSig = engine.signal(t.length)\n signalsMap.set('length', lengthSig)\n }\n return lengthSig.subscribe(cb)\n }\n }\n\n if (Array.isArray(t) && typeof prop === 'string' && ['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse'].includes(prop)) {\n return (...args: any[]) => {\n let result: any\n engine.batch(() => {\n result = (Reflect.get(t, prop) as Function).apply(receiver, args)\n\n let lengthSig = signalsMap.get('length')\n if (lengthSig) lengthSig.value = t.length\n\n signalsMap.forEach((sig: any, key: string) => {\n if (key !== 'length') sig.value = Reflect.get(t, key)\n })\n })\n return result\n }\n }\n\n if (typeof prop === 'symbol' || prop === 'constructor' || prop === 'toJSON') return Reflect.get(t, prop, receiver)\n\n let sig = signalsMap.get(prop)\n if (!sig) {\n const rawValue = Reflect.get(t, prop)\n sig = engine.signal(rawValue)\n signalsMap.set(prop, sig)\n\n // ⚡ ЛЕНИВОЕ КЭШИРОВАНИЕ НА ЧТЕНИИ (O(1) Hot Path):\n // Создаем прокси-обертку строго один раз при первом РЕАЛЬНОМ обращении к свойству,\n // а не принудительно при записи.\n if (rawValue !== null && typeof rawValue === 'object') {\n (sig as any)._proxyCache = engine.reactive(rawValue, name ? `${name}.${String(prop)}` : String(prop))\n }\n }\n\n if ((sig as any)._proxyCache !== undefined) {\n sig.value // Честная регистрация ребра для сохранения топологии глубины веток\n return (sig as any)._proxyCache\n }\n\n return sig.value\n },\n\n set(t: T, prop: string | symbol, value: any, receiver: any) {\n const rawValue = engine.proxyTargets.has(value) ? value : value\n const oldValue = Reflect.get(t, prop)\n\n if (oldValue === rawValue && prop !== 'length') return true\n Reflect.set(t, prop, rawValue)\n\n let sig = signalsMap.get(prop)\n if (!sig) {\n sig = engine.signal(oldValue)\n signalsMap.set(prop, sig)\n }\n\n // ⚡ МЕГА-УСКOРЕНИЕ ДЛЯ СЕТТЕРOВ:\n // При записи мы просто СБРАСЫВАЕМ кэш прокси на узле в undefined.\n // Если бенчмарк захочет прочитать это свойство на следующей итерации,\n // ловушка геттера лениво создаст прокси. Если нет — мы сэкономили 100% ресурсов!\n (sig as any)._proxyCache = undefined\n sig.value = rawValue\n\n if (Array.isArray(t) && prop !== 'length') {\n let lengthSig = signalsMap.get('length')\n if (lengthSig) lengthSig.value = t.length\n }\n return true\n }\n }\n\n const proxy = new Proxy(target, handler)\n engine.proxyCache.set(target, proxy)\n engine.proxyTargets.add(proxy)\n return proxy\n}\n"],"mappings":";AAGA,SAAgB,EACd,GACA,GACA,GACG;CACH,IAAI,EAAO,aAAa,IAAI,CAAM,GAAG,OAAO;CAC5C,IAAI,EAAO,WAAW,IAAI,CAAM,GAAG,OAAO,EAAO,WAAW,IAAI,CAAM;CACtE,AAAK,EAAO,gBAAgB,IAAI,CAAM,KAAG,EAAO,gBAAgB,IAAI,mBAAQ,IAAI,IAAI,CAAC;CACrF,IAAM,IAAa,EAAO,gBAAgB,IAAI,CAAM,GAoF9C,IAAQ,IAAI,MAAM,GAAQ;EAjF9B,IAAI,GAAM,GAAuB,GAAe;GAC9C,IAAI,MAAS,iBAAiB,MAAM,QAAQ,CAAC,GAC3C,QAAQ,MAAmB;IACzB,IAAI,IAAY,EAAW,IAAI,QAAQ;IAKvC,OAJK,MACH,IAAY,EAAO,OAAO,EAAE,MAAM,GAClC,EAAW,IAAI,UAAU,CAAS,IAE7B,EAAU,UAAU,CAAE;GAC/B;GAGF,IAAI,MAAM,QAAQ,CAAC,KAAK,OAAO,KAAS,YAAY;IAAC;IAAQ;IAAO;IAAS;IAAW;IAAU;IAAQ;GAAS,CAAC,CAAC,SAAS,CAAI,GAChI,QAAQ,GAAG,MAAgB;IACzB,IAAI;IAWJ,OAVA,EAAO,YAAY;KACjB,IAAU,QAAQ,IAAI,GAAG,CAAI,CAAC,CAAc,MAAM,GAAU,CAAI;KAEhE,IAAI,IAAY,EAAW,IAAI,QAAQ;KAGvC,AAFI,MAAW,EAAU,QAAQ,EAAE,SAEnC,EAAW,SAAS,GAAU,MAAgB;MAC5C,AAAI,MAAQ,aAAU,EAAI,QAAQ,QAAQ,IAAI,GAAG,CAAG;KACtD,CAAC;IACH,CAAC,GACM;GACT;GAGF,IAAI,OAAO,KAAS,YAAY,MAAS,iBAAiB,MAAS,UAAU,OAAO,QAAQ,IAAI,GAAG,GAAM,CAAQ;GAEjH,IAAI,IAAM,EAAW,IAAI,CAAI;GAC7B,IAAI,CAAC,GAAK;IACR,IAAM,IAAW,QAAQ,IAAI,GAAG,CAAI;IAOpC,AANA,IAAM,EAAO,OAAO,CAAQ,GAC5B,EAAW,IAAI,GAAM,CAAG,GAKC,OAAO,KAAa,YAAzC,MACF,EAAa,cAAc,EAAO,SAAS,GAAU,IAAO,GAAG,EAAK,GAAG,OAAO,CAAI,MAAM,OAAO,CAAI,CAAC;GAExG;GAOA,OALK,EAAY,gBAAgB,KAAA,IAK1B,EAAI,SAJT,EAAI,OACI,EAAY;EAIxB;EAEA,IAAI,GAAM,GAAuB,GAAY,GAAe;GAC1D,IAAM,KAAW,EAAO,aAAa,IAAI,CAAK,GAAI,IAC5C,IAAW,QAAQ,IAAI,GAAG,CAAI;GAEpC,IAAI,MAAa,KAAY,MAAS,UAAU,OAAO;GACvD,QAAQ,IAAI,GAAG,GAAM,CAAQ;GAE7B,IAAI,IAAM,EAAW,IAAI,CAAI;GAa7B,IAZK,MACH,IAAM,EAAO,OAAO,CAAQ,GAC5B,EAAW,IAAI,GAAM,CAAG,IAO1B,EAAa,cAAc,KAAA,GAC3B,EAAI,QAAQ,GAER,MAAM,QAAQ,CAAC,KAAK,MAAS,UAAU;IACzC,IAAI,IAAY,EAAW,IAAI,QAAQ;IACvC,AAAI,MAAW,EAAU,QAAQ,EAAE;GACrC;GACA,OAAO;EACT;CAG8B,CAAO;CAGvC,OAFA,EAAO,WAAW,IAAI,GAAQ,CAAK,GACnC,EAAO,aAAa,IAAI,CAAK,GACtB;AACT"}
|
|
1
|
+
{"version":3,"file":"core.method.reactive.mjs","names":[],"sources":["../src/core/core.method.reactive.ts"],"sourcesContent":["import { SignalOptions } from './types'\n\nexport function createReactive<T extends object>(\n engine: any,\n target: T,\n name?: string\n): T {\n if (target === null || typeof target !== 'object') {\n return target\n }\n\n // 1. Возвращаем уже существующий Proxy из кэша ядра\n if (engine.proxyCache.has(target)) {\n return engine.proxyCache.get(target) as T\n }\n if (engine.proxyTargets.has(target)) {\n return target\n }\n\n const signalMap = new Map<string | symbol, any>()\n engine.reactiveSignals.set(target, signalMap)\n\n // Внутренний скрытый сигнал длины для массивов\n let lenSignal: any = null\n if (Array.isArray(target)) {\n lenSignal = engine.signal(target.length, `[RE-INTERNAL]:len:${name || 'array'}`)\n }\n\n // ⚡ ВЫСОКОСКОРОСТНАЯ ИНСТРУМЕНТАЦИЯ НАТИВНЫХ МЕТОДОВ МАССИВОВ\n const arrayInstrumentations: Record<string | symbol, Function> = {\n push(...args: any[]) {\n const rawTarget = target as any\n return engine.batch(() => {\n const res = Array.prototype.push.apply(rawTarget, args)\n if (lenSignal) lenSignal.value = rawTarget.length\n // Пинаем подписчиков на свойства\n notifyKeyChange(rawTarget, 'length')\n return res\n })\n },\n pop() {\n const rawTarget = target as any\n return engine.batch(() => {\n const res = Array.prototype.pop.apply(rawTarget)\n if (lenSignal) lenSignal.value = rawTarget.length\n notifyKeyChange(rawTarget, 'length')\n return res\n })\n },\n shift() {\n const rawTarget = target as any\n return engine.batch(() => {\n const res = Array.prototype.shift.apply(rawTarget)\n if (lenSignal) lenSignal.value = rawTarget.length\n notifyKeyChange(rawTarget, 'length')\n return res\n })\n },\n unshift(...args: any[]) {\n const rawTarget = target as any\n return engine.batch(() => {\n const res = Array.prototype.unshift.apply(rawTarget, args)\n if (lenSignal) lenSignal.value = rawTarget.length\n notifyKeyChange(rawTarget, 'length')\n return res\n })\n },\n splice(...args: any[]) {\n const rawTarget = target as any\n return engine.batch(() => {\n // Приведение к any снимает строгую проверку кортежа аргументов [start, deleteCount]\n const res = (Array.prototype.splice as any).apply(rawTarget, args)\n if (lenSignal) lenSignal.value = rawTarget.length\n notifyKeyChange(rawTarget, 'length')\n return res\n })\n },\n reverse() {\n const rawTarget = target as any\n return engine.batch(() => {\n const res = Array.prototype.reverse.apply(rawTarget)\n if (lenSignal) {\n lenSignal.value = rawTarget.length\n }\n\n // ⚛️ ЧЕСТНЫЙ ПЕРЕБОР ИНДЕКСОВ: Оповещаем подписчиков, которые следят за\n // конкретными элементами массива по числовым ключам (state.numbers[0])\n for (let i = 0; i < rawTarget.length; i++) {\n notifyKeyChange(rawTarget, String(i))\n notifyKeyChange(rawTarget, String(i))\n }\n\n notifyKeyChange(rawTarget, 'length')\n return res\n })\n },\n sort(compareFn?: (a: any, b: any) => number) {\n const rawTarget = target as any\n return engine.batch(() => {\n const res = (Array.prototype.sort as any).apply(rawTarget, [compareFn])\n if (lenSignal) lenSignal.value = rawTarget.length\n notifyKeyChange(rawTarget, 'length')\n return res\n })\n }\n }\n\n function notifyKeyChange(rawTarget: any, key: string | symbol) {\n const map = engine.reactiveSignals.get(rawTarget)\n if (map) {\n const sig = map.get(key)\n if (sig) {\n // Симулируем пинок изменения объекта самому себе через инкремент версии\n sig.value = (sig.value || 0) + 1\n }\n }\n }\n\n const handler: ProxyHandler<any> = {\n get(rawTarget, key, receiver) {\n if (key === '__isProxy') return true\n if (key === '_target') return rawTarget\n if (key === '_lenSignal') return lenSignal\n\n // Если это массив и вызывается деструктивный метод — отдаем атомарный мутатор\n if (Array.isArray(rawTarget) && Object.prototype.hasOwnProperty.call(arrayInstrumentations, key)) {\n return arrayInstrumentations[key].bind(receiver)\n }\n\n // Если мы находимся в реактивном контексте — подписываем текущий ключ\n if (engine.activeConsumer) {\n let sig = signalMap.get(key)\n if (!sig) {\n sig = engine.signal(0, `reactive:${name || 'object'}:${String(key)}`)\n signalMap.set(key, sig)\n }\n // Считываем значение сигнала для автоматической регистрации ребра графа\n sig.value\n if (key === 'length' && lenSignal) {\n lenSignal.value\n }\n }\n\n const res = Reflect.get(rawTarget, key, receiver)\n\n // Ленивое глубокое Proxy-проксирование на лету\n if (res !== null && typeof res === 'object') {\n return createReactive(engine, res, `${name || 'object'}.${String(key)}`)\n }\n return res\n },\n\n set(rawTarget, key, newValue, receiver) {\n const oldValue = Reflect.get(rawTarget, key, receiver)\n\n // Прерываем холостые мутации примитивов по Object.is\n if (Object.is(oldValue, newValue) && key !== 'length') {\n return true\n }\n\n const res = Reflect.set(rawTarget, key, newValue, receiver)\n if (res) {\n // Каскадно уведомляем граф через скрытый сигнальный маркер ключа\n let sig = signalMap.get(key)\n if (sig) {\n sig.value = (sig.value || 0) + 1\n }\n if (Array.isArray(rawTarget) && key !== 'length' && lenSignal) {\n // Принудительно триггерим длину, если изменился индекс массива\n lenSignal.value = rawTarget.length\n }\n }\n return res\n },\n\n deleteProperty(rawTarget, key) {\n const hasKey = Reflect.has(rawTarget, key)\n const res = Reflect.deleteProperty(rawTarget, key)\n if (res && hasKey) {\n let sig = signalMap.get(key)\n if (sig) {\n sig.value = (sig.value || 0) + 1\n }\n if (Array.isArray(rawTarget) && lenSignal) {\n lenSignal.value = rawTarget.length\n }\n }\n return res\n },\n\n ownKeys(rawTarget) {\n if (engine.activeConsumer) {\n let sig = signalMap.get('__ownKeys__')\n if (!sig) {\n sig = engine.signal(0, `reactive:${name || 'object'}:__ownKeys__`)\n signalMap.set('__ownKeys__', sig)\n }\n sig.value\n }\n return Reflect.ownKeys(rawTarget)\n }\n }\n\n const proxy = new Proxy(target, handler)\n engine.proxyCache.set(target, proxy)\n engine.proxyTargets.add(proxy)\n\n return proxy as T\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require("./utils/getExtractedValues.cjs");function t(t,n,r){let i=n,a=0,o=typeof r==`string`?r:r?.name
|
|
1
|
+
const e=require("./utils/getExtractedValues.cjs");function t(t,n,r){let i=n,a=0,o=typeof r==`string`?r:r?.name;o&&e.getExtractedValues({tested:[o],expectedKey:`CORE_INTERNAL_SIGNAL`,valueType:`number`})?.[0];let s=new Set,c=!1,l=n,u={type:`signal`,get version(){return a},subscribers:s},d=(e=2)=>{for(let n of s){let r=n._node||n;if(r.type===`effect`)r.isDirty=!0,t.scheduleEffect(n);else if(r.type===`computed`)r.markDirty&&r.markDirty(e);else if(typeof n==`function`)try{n(i)}catch(e){console.error(e)}else if(n&&typeof n.run==`function`)try{n.run()}catch(e){console.error(e)}}},f={get value(){let e=t.activeConsumer;if(e){s.add(t.activeConsumer),t.activeConsumer.dependencies.add(f);let n=e._node||e;n.depth!==void 0&&n.depth===1&&(n.depth=2),e.activeRunId!==void 0&&(f._lastSeenInRunId=e.activeRunId)}return i},set value(e){if(!(Object.is(i,e)&&!(i===e&&typeof i==`object`&&i))){if(r&&typeof r==`object`&&r.validate){let t=r.validate(e);if(t!==!0){console.error(typeof t==`string`?t:`[Validation Error]`);return}}if(t.batchDepth>0){c||(c=!0,l=i),i=e,f.hasBatchValue=!0,d(1),t.batchedSignals.add(f);return}i=e,a++,t.epoch++,d(2),t.batchDepth===0&&t.flushEffects()}},get version(){return a},type:`signal`,subscribe(e){return s.add(e),e(i),()=>{s.delete(e)}},_applyBatchValue:()=>c&&(!Object.is(l,i)||typeof i==`object`&&i)?(a++,!0):!1,_flushBatch:(e,n)=>{c&&(e?(n||t.epoch++,d(1)):d(0),c=!1,f.hasBatchValue=!1,l=i)}};return f._node=u,f.subscribers=s,f}exports.createSignal=t;
|
|
2
2
|
//# sourceMappingURL=core.method.signal.cjs.map
|