@pravosleva/reactive-engine 2.5.0-alpha.4 → 2.5.0-alpha.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +68 -69
- 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 +86 -192
- 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.6.umd.js +13 -0
- package/dist/reactive-engine@2.5.0-alpha.6.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.4.umd.js +0 -13
- package/dist/reactive-engine@2.5.0-alpha.4.umd.js.map +0 -1
|
@@ -1,92 +1,91 @@
|
|
|
1
1
|
//#region src/core/core.method.computed.ts
|
|
2
2
|
function e(e, t, n) {
|
|
3
3
|
let r = t.toString(), i = n ? `${n}:${r}` : r;
|
|
4
|
-
e.computedStringCache ||= /* @__PURE__ */ new Map()
|
|
5
|
-
|
|
4
|
+
if (e.computedStringCache ||= /* @__PURE__ */ new Map(), e.batchDepth > 0) {
|
|
5
|
+
let t = e.computedStringCache.get(i);
|
|
6
|
+
if (t) return t;
|
|
7
|
+
}
|
|
8
|
+
let a = e.computedCache.get(t);
|
|
6
9
|
if (a) {
|
|
7
10
|
let t = a._node || a;
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
let o = e.computedCache.get(t);
|
|
11
|
-
if (o) {
|
|
12
|
-
let t = o._node || o;
|
|
13
|
-
return e.batchDepth > 0 || t.subscribers.size === 0 && (t.state = 2), o;
|
|
11
|
+
if (e.batchDepth === 0) t.state = 2;
|
|
12
|
+
else return a;
|
|
14
13
|
}
|
|
15
|
-
let
|
|
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) => {
|
|
16
15
|
if (!e) return;
|
|
17
16
|
let t = e._node || e;
|
|
18
17
|
if (t.dependencies && t.dependencies.size > 0) {
|
|
19
18
|
for (let n of t.dependencies) {
|
|
20
19
|
let r = n, i = r._node || r;
|
|
21
|
-
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));
|
|
22
21
|
}
|
|
23
22
|
t.dependencies.clear(), t.depVersions && t.depVersions.clear();
|
|
24
23
|
}
|
|
25
|
-
},
|
|
24
|
+
}, v = -1, y = (t) => {
|
|
26
25
|
let n = e.batchIterationId;
|
|
27
|
-
if (n !== void 0 &&
|
|
28
|
-
if (!
|
|
29
|
-
if (
|
|
26
|
+
if (n !== void 0 && f === n || u === e.epoch && l && d === 0) return !1;
|
|
27
|
+
if (!l || d === 2) return t.run();
|
|
28
|
+
if (v === e.epoch && e.batchDepth === 0) return !1;
|
|
30
29
|
let r = !1;
|
|
31
|
-
if (
|
|
30
|
+
if (p && p.size > 0) for (let e of p) {
|
|
32
31
|
let t = e._node || e;
|
|
33
|
-
if (t.type === "computed" && t.update && t.update(), e.hasBatchValue ||
|
|
32
|
+
if (t.type === "computed" && t.update && t.update(), e.hasBatchValue || m.get(e) !== t.version) {
|
|
34
33
|
r = !0;
|
|
35
34
|
break;
|
|
36
35
|
}
|
|
37
36
|
}
|
|
38
|
-
return
|
|
39
|
-
},
|
|
37
|
+
return v = e.epoch, r || s ? t.run() : (d = 0, !1);
|
|
38
|
+
}, b = 0, x = {
|
|
40
39
|
id: e.subscriberId++,
|
|
41
|
-
dependencies:
|
|
42
|
-
subscribers:
|
|
43
|
-
ownedEffects:
|
|
40
|
+
dependencies: p,
|
|
41
|
+
subscribers: g,
|
|
42
|
+
ownedEffects: h,
|
|
44
43
|
depth: 1,
|
|
45
44
|
type: "computed",
|
|
46
45
|
fn: t,
|
|
47
46
|
get version() {
|
|
48
|
-
return
|
|
47
|
+
return c;
|
|
49
48
|
},
|
|
50
49
|
get state() {
|
|
51
|
-
return
|
|
50
|
+
return d;
|
|
52
51
|
},
|
|
53
52
|
set state(e) {
|
|
54
|
-
|
|
53
|
+
d = e;
|
|
55
54
|
},
|
|
56
55
|
get depVersions() {
|
|
57
|
-
return
|
|
56
|
+
return m;
|
|
58
57
|
},
|
|
59
|
-
update: () =>
|
|
58
|
+
update: () => y(x),
|
|
60
59
|
run: () => {
|
|
61
60
|
let r = e.batchIterationId;
|
|
62
|
-
if (r !== void 0 &&
|
|
63
|
-
if (
|
|
64
|
-
e.cycleDetectionStack.add(
|
|
61
|
+
if (r !== void 0 && f === r || u === e.epoch && l && d === 0) return !1;
|
|
62
|
+
if (u = e.epoch, v = e.epoch, r !== void 0 && (f = r), e.cycleDetectionStack.has(x)) throw Error("[Graph Error] Cyclic dependency detected");
|
|
63
|
+
e.cycleDetectionStack.add(x);
|
|
65
64
|
let i = e.activeConsumer, a = e.activeOwner;
|
|
66
|
-
e.activeConsumer =
|
|
67
|
-
let
|
|
68
|
-
if (
|
|
69
|
-
|
|
65
|
+
e.activeConsumer = x, e.activeOwner = x, b++, x.activeRunId = b, e._poolArr ||= [];
|
|
66
|
+
let g = e._poolArr;
|
|
67
|
+
if (g.length = 0, p.size > 0) for (let e of p) g.push(e);
|
|
68
|
+
p.clear();
|
|
70
69
|
try {
|
|
71
|
-
if (
|
|
72
|
-
for (let e of
|
|
73
|
-
|
|
70
|
+
if (h.size > 0) {
|
|
71
|
+
for (let e of h) e && typeof e.dispose == "function" && e.dispose();
|
|
72
|
+
h.clear();
|
|
74
73
|
}
|
|
75
74
|
let r = t();
|
|
76
|
-
if (
|
|
77
|
-
let e =
|
|
78
|
-
for (let t = 0; t <
|
|
79
|
-
let n =
|
|
80
|
-
if (!e || !
|
|
75
|
+
if (g.length > 0) {
|
|
76
|
+
let e = g.length === p.size;
|
|
77
|
+
for (let t = 0; t < g.length; t++) {
|
|
78
|
+
let n = g[t];
|
|
79
|
+
if (!e || !p.has(n)) {
|
|
81
80
|
let e = n._node || n;
|
|
82
|
-
e.subscribers && e.subscribers.delete(
|
|
81
|
+
e.subscribers && e.subscribers.delete(x), m.delete(n);
|
|
83
82
|
}
|
|
84
83
|
}
|
|
85
84
|
}
|
|
86
|
-
let i =
|
|
85
|
+
let i = s || !Object.is(o, r);
|
|
87
86
|
if (i) {
|
|
88
87
|
let t;
|
|
89
|
-
e.log && n && e.logger && e.logger.isEnabled && (t =
|
|
88
|
+
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({
|
|
90
89
|
type: "computed",
|
|
91
90
|
label: n,
|
|
92
91
|
details: {
|
|
@@ -95,44 +94,44 @@ function e(e, t, n) {
|
|
|
95
94
|
}
|
|
96
95
|
});
|
|
97
96
|
}
|
|
98
|
-
|
|
97
|
+
s = !1, d = 0, l = !0;
|
|
99
98
|
let a = 0;
|
|
100
|
-
for (let e of
|
|
99
|
+
for (let e of p) {
|
|
101
100
|
let t = e, n = t._node || t;
|
|
102
|
-
|
|
101
|
+
m.set(t, n.version), n.subscribers && n.subscribers.add(x), n.depth !== void 0 && n.depth > a && (a = n.depth);
|
|
103
102
|
}
|
|
104
|
-
return
|
|
103
|
+
return x.depth = a + 1, i;
|
|
105
104
|
} finally {
|
|
106
|
-
e.activeConsumer = i, e.activeOwner = a, e.cycleDetectionStack.delete(
|
|
105
|
+
e.activeConsumer = i, e.activeOwner = a, e.cycleDetectionStack.delete(x);
|
|
107
106
|
}
|
|
108
107
|
},
|
|
109
108
|
markDirty: (t) => {
|
|
110
|
-
if (!(
|
|
111
|
-
|
|
112
|
-
for (let t of
|
|
109
|
+
if (!(d >= t)) {
|
|
110
|
+
d = t;
|
|
111
|
+
for (let t of g) {
|
|
113
112
|
let n = t._node || t;
|
|
114
113
|
n.type === "effect" ? (n.isDirty = !0, e.scheduleEffect(t)) : n.markDirty && n.markDirty(1);
|
|
115
114
|
}
|
|
116
115
|
}
|
|
117
116
|
}
|
|
118
|
-
},
|
|
117
|
+
}, S = {
|
|
119
118
|
get value() {
|
|
120
119
|
let t = e.activeConsumer;
|
|
121
|
-
if (t && t !==
|
|
122
|
-
|
|
123
|
-
let e =
|
|
124
|
-
n.depth !== void 0 && e >= n.depth && (n.depth = e + 1), t.activeRunId !== void 0 && (
|
|
120
|
+
if (t && t !== x) {
|
|
121
|
+
g.add(t), t.dependencies.add(x);
|
|
122
|
+
let e = x.depth || 1, n = t._node || t;
|
|
123
|
+
n.depth !== void 0 && e >= n.depth && (n.depth = e + 1), t.activeRunId !== void 0 && (x._lastSeenInRunId = t.activeRunId);
|
|
125
124
|
}
|
|
126
|
-
return
|
|
125
|
+
return y(x), t && t.depVersions && t.depVersions.set(S, c), o;
|
|
127
126
|
},
|
|
128
127
|
get valueWithoutTracking() {
|
|
129
|
-
return
|
|
128
|
+
return o;
|
|
130
129
|
},
|
|
131
130
|
get version() {
|
|
132
|
-
return
|
|
131
|
+
return c;
|
|
133
132
|
},
|
|
134
133
|
get dependencies() {
|
|
135
|
-
return
|
|
134
|
+
return p;
|
|
136
135
|
},
|
|
137
136
|
subscribe(t) {
|
|
138
137
|
let n = {
|
|
@@ -143,21 +142,21 @@ function e(e, t, n) {
|
|
|
143
142
|
type: "effect",
|
|
144
143
|
run: () => {
|
|
145
144
|
if (!n.isDisposed) try {
|
|
146
|
-
t(
|
|
145
|
+
t(S.value);
|
|
147
146
|
} catch (e) {
|
|
148
147
|
console.error(e);
|
|
149
148
|
}
|
|
150
149
|
}
|
|
151
150
|
};
|
|
152
|
-
return
|
|
153
|
-
n.isDisposed = !0,
|
|
151
|
+
return g.add(n), t(S.value), () => {
|
|
152
|
+
n.isDisposed = !0, g.delete(n);
|
|
154
153
|
};
|
|
155
154
|
},
|
|
156
155
|
subscribeState(e) {
|
|
157
|
-
return
|
|
156
|
+
return S.subscribe(e);
|
|
158
157
|
},
|
|
159
158
|
destroy: () => {
|
|
160
|
-
|
|
159
|
+
_(x), g && g.clear(), e.computedCache.delete(t), e.computedStringCache && e.computedStringCache.delete(i), s = !0, d = 2, l = !1;
|
|
161
160
|
},
|
|
162
161
|
__subscribe(t) {
|
|
163
162
|
let n = {
|
|
@@ -166,12 +165,12 @@ function e(e, t, n) {
|
|
|
166
165
|
run: t,
|
|
167
166
|
isDirty: !1
|
|
168
167
|
};
|
|
169
|
-
return
|
|
170
|
-
|
|
168
|
+
return g.add(n), () => {
|
|
169
|
+
g.delete(n);
|
|
171
170
|
};
|
|
172
171
|
}
|
|
173
172
|
};
|
|
174
|
-
return
|
|
173
|
+
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;
|
|
175
174
|
}
|
|
176
175
|
//#endregion
|
|
177
176
|
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 // ⚡ ЭКСТРЕМЕЛЬНАЯ ДЕДУПЛИКАЦИЯ СТРОК ИЗ ВЕРСИИ 2.3.16-alpha\n const fnSourceKey = fn.toString()\n // Добавляем signalName (имя слоя) в ключ, чтобы изолировать слои внутри батча\n const cacheKey = signalName ? `${signalName}:${fnSourceKey}` : fnSourceKey\n\n if (!engine.computedStringCache) {\n engine.computedStringCache = new Map<string, any>()\n }\n\n // 1. ГОРЯЧИЙ ПУТЬ БЕНЧМАРКА: Мгновенный возврат прогретой ноды БЕЗ аллокаций памяти\n const existingStringNode = engine.computedStringCache.get(cacheKey)\n if (existingStringNode) {\n const actNode = existingStringNode._node || existingStringNode\n\n // Если мы в батче, мы на 100% доверяем персистентному кэшу схемы графа\n if (engine.batchDepth > 0) {\n return existingStringNode as Computed<T>\n }\n\n // Вне батча (прогон сьюта) проверяем лексический контекст замыкания\n if (actNode.subscribers.size === 0) {\n actNode.state = 2 // DIRTY\n }\n return existingStringNode as Computed<T>\n }\n\n // 2. ВТОРИЧНАЯ КАНОНИЧЕСКАЯ ПРОВЕРКА ПО ССЫЛКЕ ФУНКЦИИ\n const existingWeakNode = engine.computedCache.get(fn)\n if (existingWeakNode) {\n const actNode = existingWeakNode._node || existingWeakNode\n if (engine.batchDepth > 0) {\n return existingWeakNode as Computed<T>\n }\n if (actNode.subscribers.size === 0) {\n actNode.state = 2 // DIRTY\n }\n return existingWeakNode as Computed<T>\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 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 // ⚛️ ВЫСОКОСКОРОСТНОЙ МАССИВ ПУЛА (0% аллокаций памяти из 2.3.16)\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 computedInstance.run = () => computedNode.run()\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 // 1. Изолированный транзакционный текстовый кэш батча (Защита DieHard от Churn)\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 // 2. Канонический WeakMap путь (Главный источник правды связанных графов)\n const existingWeak = engine.computedCache.get(fn)\n if (existingWeak) {\n const actNode = existingWeak._node || existingWeak\n\n // ⚛️ ФИКС КОЛЛИЗИИ С ПОДПИСЧИКОМ: Если мы вне батча, мы ВСЕГДА принудительно\n // сбрасываем состояние узла в DIRTY (2), обязывая его честно выполнить fn()\n // и обновить лексический скоуп замыкания, независимо от живых подписчиков!\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 if (currentBatchIteration !== undefined && lastEvaluatedIteration === currentBatchIteration) {\n return false\n }\n\n // ⚛️ ФИКС АЛМАЗНОГО ГЛИЧА: Сквозной аппаратный барьер по эпохе ядра изменений.\n // Если в рамках текущего кванта времени узел уже рассчитывался и перешел\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) {\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) {\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 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 computedInstance.run = () => computedNode.run()\n engine.computedCache.set(fn, computedInstance)\n if (engine.batchDepth > 0) {\n engine.computedStringCache.set(cacheKey, computedInstance)\n }\n ;(computedInstance as any)._node = computedNode\n ;(computedInstance as any).subscribers = subscribers\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":"AAEA,SAAgB,EACd,EACA,EACA,EACG,CACH,GAAuB,OAAO,GAAW,WAArC,EACF,OAAO,EAIT,GAAI,EAAO,WAAW,IAAI,CAAM,EAC9B,OAAO,EAAO,WAAW,IAAI,CAAM,EAErC,GAAI,EAAO,aAAa,IAAI,CAAM,EAChC,OAAO,EAGT,IAAM,EAAY,IAAI,IACtB,EAAO,gBAAgB,IAAI,EAAQ,CAAS,EAG5C,IAAI,EAAiB,KACjB,MAAM,QAAQ,CAAM,IACtB,EAAY,EAAO,OAAO,EAAO,OAAQ,qBAAqB,GAAQ,SAAS,GAIjF,IAAM,EAA2D,CAC/D,KAAK,GAAG,EAAa,CACnB,IAAM,EAAY,EAClB,OAAO,EAAO,UAAY,CACxB,IAAM,EAAM,MAAM,UAAU,KAAK,MAAM,EAAW,CAAI,EAItD,OAHI,IAAW,EAAU,MAAQ,EAAU,QAE3C,EAAgB,EAAW,QAAQ,EAC5B,CACT,CAAC,CACH,EACA,KAAM,CACJ,IAAM,EAAY,EAClB,OAAO,EAAO,UAAY,CACxB,IAAM,EAAM,MAAM,UAAU,IAAI,MAAM,CAAS,EAG/C,OAFI,IAAW,EAAU,MAAQ,EAAU,QAC3C,EAAgB,EAAW,QAAQ,EAC5B,CACT,CAAC,CACH,EACA,OAAQ,CACN,IAAM,EAAY,EAClB,OAAO,EAAO,UAAY,CACxB,IAAM,EAAM,MAAM,UAAU,MAAM,MAAM,CAAS,EAGjD,OAFI,IAAW,EAAU,MAAQ,EAAU,QAC3C,EAAgB,EAAW,QAAQ,EAC5B,CACT,CAAC,CACH,EACA,QAAQ,GAAG,EAAa,CACtB,IAAM,EAAY,EAClB,OAAO,EAAO,UAAY,CACxB,IAAM,EAAM,MAAM,UAAU,QAAQ,MAAM,EAAW,CAAI,EAGzD,OAFI,IAAW,EAAU,MAAQ,EAAU,QAC3C,EAAgB,EAAW,QAAQ,EAC5B,CACT,CAAC,CACH,EACA,OAAO,GAAG,EAAa,CACrB,IAAM,EAAY,EAClB,OAAO,EAAO,UAAY,CAExB,IAAM,EAAO,MAAM,UAAU,OAAe,MAAM,EAAW,CAAI,EAGjE,OAFI,IAAW,EAAU,MAAQ,EAAU,QAC3C,EAAgB,EAAW,QAAQ,EAC5B,CACT,CAAC,CACH,EACA,SAAU,CACR,IAAM,EAAY,EAClB,OAAO,EAAO,UAAY,CACxB,IAAM,EAAM,MAAM,UAAU,QAAQ,MAAM,CAAS,EAC/C,IACF,EAAU,MAAQ,EAAU,QAK9B,IAAK,IAAI,EAAI,EAAG,EAAI,EAAU,OAAQ,IACpC,EAAgB,EAAW,OAAO,CAAC,CAAC,EACpC,EAAgB,EAAW,OAAO,CAAC,CAAC,EAItC,OADA,EAAgB,EAAW,QAAQ,EAC5B,CACT,CAAC,CACH,EACA,KAAK,EAAwC,CAC3C,IAAM,EAAY,EAClB,OAAO,EAAO,UAAY,CACxB,IAAM,EAAO,MAAM,UAAU,KAAa,MAAM,EAAW,CAAC,CAAS,CAAC,EAGtE,OAFI,IAAW,EAAU,MAAQ,EAAU,QAC3C,EAAgB,EAAW,QAAQ,EAC5B,CACT,CAAC,CACH,CACF,EAEA,SAAS,EAAgB,EAAgB,EAAsB,CAC7D,IAAM,EAAM,EAAO,gBAAgB,IAAI,CAAS,EAChD,GAAI,EAAK,CACP,IAAM,EAAM,EAAI,IAAI,CAAG,EACnB,IAEF,EAAI,OAAS,EAAI,OAAS,GAAK,EAEnC,CACF,CAuFA,IAAM,EAAQ,IAAI,MAAM,EAAQ,CApF9B,IAAI,EAAW,EAAK,EAAU,CAC5B,GAAI,IAAQ,YAAa,MAAO,GAChC,GAAI,IAAQ,UAAW,OAAO,EAC9B,GAAI,IAAQ,aAAc,OAAO,EAGjC,GAAI,MAAM,QAAQ,CAAS,GAAK,OAAO,UAAU,eAAe,KAAK,EAAuB,CAAG,EAC7F,OAAO,EAAsB,EAAI,CAAC,KAAK,CAAQ,EAIjD,GAAI,EAAO,eAAgB,CACzB,IAAI,EAAM,EAAU,IAAI,CAAG,EACtB,IACH,EAAM,EAAO,OAAO,EAAG,YAAY,GAAQ,SAAS,GAAG,OAAO,CAAG,GAAG,EACpE,EAAU,IAAI,EAAK,CAAG,GAGxB,EAAI,MACA,IAAQ,UAAY,GACtB,EAAU,KAEd,CAEA,IAAM,EAAM,QAAQ,IAAI,EAAW,EAAK,CAAQ,EAMhD,OAHoB,OAAO,GAAQ,UAA/B,EACK,EAAe,EAAQ,EAAK,GAAG,GAAQ,SAAS,GAAG,OAAO,CAAG,GAAG,EAElE,CACT,EAEA,IAAI,EAAW,EAAK,EAAU,EAAU,CACtC,IAAM,EAAW,QAAQ,IAAI,EAAW,EAAK,CAAQ,EAGrD,GAAI,OAAO,GAAG,EAAU,CAAQ,GAAK,IAAQ,SAC3C,MAAO,GAGT,IAAM,EAAM,QAAQ,IAAI,EAAW,EAAK,EAAU,CAAQ,EAC1D,GAAI,EAAK,CAEP,IAAI,EAAM,EAAU,IAAI,CAAG,EACvB,IACF,EAAI,OAAS,EAAI,OAAS,GAAK,GAE7B,MAAM,QAAQ,CAAS,GAAK,IAAQ,UAAY,IAElD,EAAU,MAAQ,EAAU,OAEhC,CACA,OAAO,CACT,EAEA,eAAe,EAAW,EAAK,CAC7B,IAAM,EAAS,QAAQ,IAAI,EAAW,CAAG,EACnC,EAAM,QAAQ,eAAe,EAAW,CAAG,EACjD,GAAI,GAAO,EAAQ,CACjB,IAAI,EAAM,EAAU,IAAI,CAAG,EACvB,IACF,EAAI,OAAS,EAAI,OAAS,GAAK,GAE7B,MAAM,QAAQ,CAAS,GAAK,IAC9B,EAAU,MAAQ,EAAU,OAEhC,CACA,OAAO,CACT,EAEA,QAAQ,EAAW,CACjB,GAAI,EAAO,eAAgB,CACzB,IAAI,EAAM,EAAU,IAAI,aAAa,EAChC,IACH,EAAM,EAAO,OAAO,EAAG,YAAY,GAAQ,SAAS,aAAa,EACjE,EAAU,IAAI,cAAe,CAAG,GAElC,EAAI,KACN,CACA,OAAO,QAAQ,QAAQ,CAAS,CAClC,CAG8B,CAAO,EAIvC,OAHA,EAAO,WAAW,IAAI,EAAQ,CAAK,EACnC,EAAO,aAAa,IAAI,CAAK,EAEtB,CACT"}
|
|
@@ -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=>{c&&(!Object.is(l,i)||typeof i==`object`&&i?(a++,e||t.epoch++,d(2)):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
|