@feng3d/reactivity 1.0.9 → 1.0.12
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/LICENSE +11 -17
- package/dist/index.js +205 -40
- package/dist/index.js.map +1 -1
- package/dist/index.umd.cjs +206 -41
- package/dist/index.umd.cjs.map +1 -1
- package/lib/arrayInstrumentations.d.ts.map +1 -1
- package/package.json +11 -12
- package/src/arrayInstrumentations.ts +1 -3
- package/src/index.ts +1 -2
- package/tsconfig.json +17 -16
package/LICENSE
CHANGED
|
@@ -1,21 +1,15 @@
|
|
|
1
|
-
MIT
|
|
1
|
+
MIT 许可证
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
版权所有 (c) 2026 feng
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
5
|
+
特此授予任何获得本软件及相关文档文件("软件")副本的人免费许可,
|
|
6
|
+
可以不受限制地处理本软件,包括但不限于使用、复制、修改、合并、
|
|
7
|
+
发布、分发、再许可和/或销售本软件的副本,并允许向其提供本软件的
|
|
8
|
+
人这样做,但须符合以下条件:
|
|
11
9
|
|
|
12
|
-
|
|
13
|
-
copies or substantial portions of the Software.
|
|
10
|
+
上述版权声明和本许可声明应包含在本软件的所有副本或主要部分中。
|
|
14
11
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
12
|
+
本软件按"原样"提供,不提供任何明示或暗示的保证,包括但不限于对
|
|
13
|
+
适销性、特定用途适用性和非侵权性的保证。在任何情况下,作者或版权
|
|
14
|
+
持有人均不对因本软件或本软件的使用或其他交易而产生的任何索赔、
|
|
15
|
+
损害或其他责任负责,无论是在合同诉讼、侵权诉讼还是其他诉讼中。
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,25 @@
|
|
|
1
|
-
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
|
+
var _a, _b;
|
|
5
|
+
const _Reactivity = class _Reactivity {
|
|
2
6
|
constructor() {
|
|
3
|
-
|
|
7
|
+
/**
|
|
8
|
+
* @private
|
|
9
|
+
*/
|
|
10
|
+
__publicField(this, "_value");
|
|
11
|
+
/**
|
|
12
|
+
* 父反应节点集合。
|
|
13
|
+
*
|
|
14
|
+
* 记录了哪些节点依赖了当前节点。
|
|
15
|
+
* 当当前节点值发生变化时,会通知所有父节点。
|
|
16
|
+
*
|
|
17
|
+
* Map 的 key 是父节点,value 是父节点的版本号。
|
|
18
|
+
* 版本号用于判断依赖关系是否过期。
|
|
19
|
+
*
|
|
20
|
+
* @private
|
|
21
|
+
*/
|
|
22
|
+
__publicField(this, "_parents", /* @__PURE__ */ new Map());
|
|
4
23
|
}
|
|
5
24
|
/**
|
|
6
25
|
* 获取当前节点值。
|
|
@@ -21,8 +40,8 @@ class Reactivity {
|
|
|
21
40
|
* 如果当前没有活动的响应式节点,或者不应该跟踪依赖,则不会建立依赖关系。
|
|
22
41
|
*/
|
|
23
42
|
track() {
|
|
24
|
-
if (!
|
|
25
|
-
const parent =
|
|
43
|
+
if (!_Reactivity.activeReactivity || !_shouldTrack) return;
|
|
44
|
+
const parent = _Reactivity.activeReactivity;
|
|
26
45
|
if (parent) {
|
|
27
46
|
this._parents.set(parent, parent._version);
|
|
28
47
|
}
|
|
@@ -47,7 +66,17 @@ class Reactivity {
|
|
|
47
66
|
});
|
|
48
67
|
this._parents.clear();
|
|
49
68
|
}
|
|
50
|
-
}
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* 当前正在执行的反应式节点。
|
|
72
|
+
*
|
|
73
|
+
* 用于在依赖收集过程中标识当前正在执行的节点。
|
|
74
|
+
* 当其他节点访问此节点的值时,会将其作为父节点。
|
|
75
|
+
*
|
|
76
|
+
* @internal
|
|
77
|
+
*/
|
|
78
|
+
__publicField(_Reactivity, "activeReactivity");
|
|
79
|
+
let Reactivity = _Reactivity;
|
|
51
80
|
function forceTrack(fn) {
|
|
52
81
|
const preShouldTrack = _shouldTrack;
|
|
53
82
|
_shouldTrack = true;
|
|
@@ -84,6 +113,7 @@ function batchRun(fn) {
|
|
|
84
113
|
}
|
|
85
114
|
if (_isRunedDeps.length > 0) {
|
|
86
115
|
_isRunedDeps.forEach((dep) => {
|
|
116
|
+
__DEV__ && console.assert(dep._isDirty === false, "dep.dirty === false");
|
|
87
117
|
dep._children.forEach((version, node) => {
|
|
88
118
|
node._parents.set(dep, dep._version);
|
|
89
119
|
});
|
|
@@ -116,10 +146,48 @@ class ComputedReactivity extends Reactivity {
|
|
|
116
146
|
*/
|
|
117
147
|
constructor(func) {
|
|
118
148
|
super();
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
149
|
+
/**
|
|
150
|
+
* 标识这是一个 ref 对象。
|
|
151
|
+
*
|
|
152
|
+
* @internal
|
|
153
|
+
*/
|
|
154
|
+
__publicField(this, "__v_isRef", true);
|
|
155
|
+
/**
|
|
156
|
+
* 计算函数。
|
|
157
|
+
*
|
|
158
|
+
* 用于计算属性值的函数,可以访问其他响应式数据。
|
|
159
|
+
* 当依赖发生变化时,会重新执行此函数。
|
|
160
|
+
*/
|
|
161
|
+
__publicField(this, "_func");
|
|
162
|
+
/**
|
|
163
|
+
* 失效子节点集合。
|
|
164
|
+
*
|
|
165
|
+
* 记录所有依赖此计算属性的子节点。
|
|
166
|
+
* 当计算属性重新计算时,会通知这些子节点。
|
|
167
|
+
*
|
|
168
|
+
* @private
|
|
169
|
+
*/
|
|
170
|
+
__publicField(this, "_children", /* @__PURE__ */ new Map());
|
|
171
|
+
/**
|
|
172
|
+
* 脏标记。
|
|
173
|
+
*
|
|
174
|
+
* 表示计算属性是否需要重新计算。
|
|
175
|
+
* 当依赖发生变化时,会设置此标记。
|
|
176
|
+
* 重新计算后会清除此标记。
|
|
177
|
+
*
|
|
178
|
+
* @private
|
|
179
|
+
*/
|
|
180
|
+
__publicField(this, "_isDirty", true);
|
|
181
|
+
/**
|
|
182
|
+
* 版本号。
|
|
183
|
+
*
|
|
184
|
+
* 每次重新计算后自动递增。
|
|
185
|
+
* 用于判断子节点中的父节点引用是否过期。
|
|
186
|
+
* 当子节点发现父节点的版本号不匹配时,会重新建立依赖关系。
|
|
187
|
+
*
|
|
188
|
+
* @private
|
|
189
|
+
*/
|
|
190
|
+
__publicField(this, "_version", -1);
|
|
123
191
|
this._func = func;
|
|
124
192
|
}
|
|
125
193
|
/**
|
|
@@ -244,9 +312,9 @@ var TriggerOpTypes = /* @__PURE__ */ ((TriggerOpTypes2) => {
|
|
|
244
312
|
TriggerOpTypes2["CLEAR"] = "clear";
|
|
245
313
|
return TriggerOpTypes2;
|
|
246
314
|
})(TriggerOpTypes || {});
|
|
247
|
-
const ITERATE_KEY = Symbol("");
|
|
248
|
-
const MAP_KEY_ITERATE_KEY = Symbol("");
|
|
249
|
-
const ARRAY_ITERATE_KEY = Symbol("");
|
|
315
|
+
const ITERATE_KEY = Symbol(__DEV__ ? "Object iterate" : "");
|
|
316
|
+
const MAP_KEY_ITERATE_KEY = Symbol(__DEV__ ? "Map keys iterate" : "");
|
|
317
|
+
const ARRAY_ITERATE_KEY = Symbol(__DEV__ ? "Array iterate" : "");
|
|
250
318
|
globalThis.__DEV__ ?? (globalThis.__DEV__ = true);
|
|
251
319
|
const isObject = (val) => val !== null && typeof val === "object";
|
|
252
320
|
const isArray = Array.isArray;
|
|
@@ -283,6 +351,9 @@ function toRaw(observed) {
|
|
|
283
351
|
const raw = observed && observed[ReactiveFlags.RAW];
|
|
284
352
|
return raw ? toRaw(raw) : observed;
|
|
285
353
|
}
|
|
354
|
+
function warn(msg, ...args) {
|
|
355
|
+
console.warn(`[警告] ${msg}`, ...args);
|
|
356
|
+
}
|
|
286
357
|
// @__NO_SIDE_EFFECTS__
|
|
287
358
|
function makeMap(str) {
|
|
288
359
|
const map = /* @__PURE__ */ Object.create(null);
|
|
@@ -296,12 +367,50 @@ class EffectScope {
|
|
|
296
367
|
* @param detached 是否创建分离的作用域
|
|
297
368
|
*/
|
|
298
369
|
constructor(detached = false) {
|
|
370
|
+
/**
|
|
371
|
+
* 作用域是否处于活动状态
|
|
372
|
+
* @internal
|
|
373
|
+
*/
|
|
374
|
+
__publicField(this, "_active", true);
|
|
375
|
+
/**
|
|
376
|
+
* 跟踪 on 方法的调用次数,允许多次调用 on 方法
|
|
377
|
+
* @internal
|
|
378
|
+
*/
|
|
379
|
+
__publicField(this, "_on", 0);
|
|
380
|
+
/**
|
|
381
|
+
* 存储当前作用域中的所有效果
|
|
382
|
+
* @internal
|
|
383
|
+
*/
|
|
384
|
+
__publicField(this, "effects", []);
|
|
385
|
+
/**
|
|
386
|
+
* 存储清理函数
|
|
387
|
+
* @internal
|
|
388
|
+
*/
|
|
389
|
+
__publicField(this, "cleanups", []);
|
|
390
|
+
/**
|
|
391
|
+
* 作用域是否被暂停
|
|
392
|
+
*/
|
|
393
|
+
__publicField(this, "_isPaused", false);
|
|
394
|
+
/**
|
|
395
|
+
* 父作用域,仅由非分离的作用域分配
|
|
396
|
+
* @internal
|
|
397
|
+
*/
|
|
398
|
+
__publicField(this, "parent");
|
|
399
|
+
/**
|
|
400
|
+
* 记录未分离的子作用域
|
|
401
|
+
* @internal
|
|
402
|
+
*/
|
|
403
|
+
__publicField(this, "scopes");
|
|
404
|
+
/**
|
|
405
|
+
* 在父作用域的 scopes 数组中记录子作用域的索引,用于优化移除操作
|
|
406
|
+
* @internal
|
|
407
|
+
*/
|
|
408
|
+
__publicField(this, "index");
|
|
409
|
+
/**
|
|
410
|
+
* 前一个作用域
|
|
411
|
+
*/
|
|
412
|
+
__publicField(this, "prevScope");
|
|
299
413
|
this.detached = detached;
|
|
300
|
-
this._active = true;
|
|
301
|
-
this._on = 0;
|
|
302
|
-
this.effects = [];
|
|
303
|
-
this.cleanups = [];
|
|
304
|
-
this._isPaused = false;
|
|
305
414
|
this.parent = activeEffectScope;
|
|
306
415
|
if (!detached && activeEffectScope) {
|
|
307
416
|
this.index = (activeEffectScope.scopes || (activeEffectScope.scopes = [])).push(
|
|
@@ -369,6 +478,8 @@ class EffectScope {
|
|
|
369
478
|
} finally {
|
|
370
479
|
activeEffectScope = currentEffectScope;
|
|
371
480
|
}
|
|
481
|
+
} else if (__DEV__) {
|
|
482
|
+
warn(`无法运行已停用的 effect 作用域。`);
|
|
372
483
|
}
|
|
373
484
|
}
|
|
374
485
|
/**
|
|
@@ -437,6 +548,10 @@ function getCurrentScope() {
|
|
|
437
548
|
function onScopeDispose(fn, failSilently = false) {
|
|
438
549
|
if (activeEffectScope) {
|
|
439
550
|
activeEffectScope.cleanups.push(fn);
|
|
551
|
+
} else if (__DEV__ && !failSilently) {
|
|
552
|
+
warn(
|
|
553
|
+
`onScopeDispose() 在没有活动的 effect 作用域时被调用,无法关联。`
|
|
554
|
+
);
|
|
440
555
|
}
|
|
441
556
|
}
|
|
442
557
|
function effect(fn) {
|
|
@@ -445,7 +560,12 @@ function effect(fn) {
|
|
|
445
560
|
const _EffectReactivity = class _EffectReactivity extends ComputedReactivity {
|
|
446
561
|
constructor(func) {
|
|
447
562
|
super(func);
|
|
448
|
-
|
|
563
|
+
/**
|
|
564
|
+
* 是否为启用, 默认为 true。
|
|
565
|
+
*
|
|
566
|
+
* 启用时,会立即执行函数。
|
|
567
|
+
*/
|
|
568
|
+
__publicField(this, "_isEnable", true);
|
|
449
569
|
if (activeEffectScope && activeEffectScope.active) {
|
|
450
570
|
activeEffectScope.effects.push(this);
|
|
451
571
|
}
|
|
@@ -509,7 +629,7 @@ const _EffectReactivity = class _EffectReactivity extends ComputedReactivity {
|
|
|
509
629
|
}
|
|
510
630
|
}
|
|
511
631
|
};
|
|
512
|
-
_EffectReactivity
|
|
632
|
+
__publicField(_EffectReactivity, "pausedQueueEffects", /* @__PURE__ */ new WeakSet());
|
|
513
633
|
let EffectReactivity = _EffectReactivity;
|
|
514
634
|
function property(target, key) {
|
|
515
635
|
let depsMap = PropertyReactivity._targetMap.get(target);
|
|
@@ -524,7 +644,21 @@ function property(target, key) {
|
|
|
524
644
|
}
|
|
525
645
|
return dep;
|
|
526
646
|
}
|
|
527
|
-
|
|
647
|
+
class PropertyReactivity extends Reactivity {
|
|
648
|
+
constructor(target, key) {
|
|
649
|
+
super();
|
|
650
|
+
__publicField(this, "_target");
|
|
651
|
+
__publicField(this, "_key");
|
|
652
|
+
this._target = target;
|
|
653
|
+
this._key = key;
|
|
654
|
+
if (target instanceof Map || target instanceof WeakMap) {
|
|
655
|
+
this._value = target.get(key);
|
|
656
|
+
} else if (target instanceof Set || target instanceof WeakSet) {
|
|
657
|
+
this._value = target.has(key);
|
|
658
|
+
} else {
|
|
659
|
+
this._value = target[key];
|
|
660
|
+
}
|
|
661
|
+
}
|
|
528
662
|
/**
|
|
529
663
|
* 获取当前节点值。
|
|
530
664
|
*
|
|
@@ -544,18 +678,6 @@ const _PropertyReactivity = class _PropertyReactivity extends Reactivity {
|
|
|
544
678
|
this.trigger();
|
|
545
679
|
this._value = v;
|
|
546
680
|
}
|
|
547
|
-
constructor(target, key) {
|
|
548
|
-
super();
|
|
549
|
-
this._target = target;
|
|
550
|
-
this._key = key;
|
|
551
|
-
if (target instanceof Map || target instanceof WeakMap) {
|
|
552
|
-
this._value = target.get(key);
|
|
553
|
-
} else if (target instanceof Set || target instanceof WeakSet) {
|
|
554
|
-
this._value = target.has(key);
|
|
555
|
-
} else {
|
|
556
|
-
this._value = target[key];
|
|
557
|
-
}
|
|
558
|
-
}
|
|
559
681
|
triggerIfChanged() {
|
|
560
682
|
}
|
|
561
683
|
/**
|
|
@@ -639,9 +761,11 @@ const _PropertyReactivity = class _PropertyReactivity extends Reactivity {
|
|
|
639
761
|
}
|
|
640
762
|
});
|
|
641
763
|
}
|
|
642
|
-
}
|
|
643
|
-
|
|
644
|
-
|
|
764
|
+
}
|
|
765
|
+
/**
|
|
766
|
+
* @private
|
|
767
|
+
*/
|
|
768
|
+
__publicField(PropertyReactivity, "_targetMap", /* @__PURE__ */ new WeakMap());
|
|
645
769
|
const arrayInstrumentations = {
|
|
646
770
|
__proto__: null,
|
|
647
771
|
/**
|
|
@@ -1122,7 +1246,6 @@ function noTracking(self, method, args = []) {
|
|
|
1122
1246
|
);
|
|
1123
1247
|
return res;
|
|
1124
1248
|
}
|
|
1125
|
-
var _a, _b;
|
|
1126
1249
|
function ref(value) {
|
|
1127
1250
|
if (isRef(value)) {
|
|
1128
1251
|
return value;
|
|
@@ -1140,7 +1263,21 @@ class RefReactivity extends (_b = Reactivity, _a = ReactiveFlags.IS_REF, _b) {
|
|
|
1140
1263
|
*/
|
|
1141
1264
|
constructor(value) {
|
|
1142
1265
|
super();
|
|
1143
|
-
|
|
1266
|
+
/**
|
|
1267
|
+
* 标识这是一个 ref 对象。
|
|
1268
|
+
*
|
|
1269
|
+
* 用于 isRef 函数判断对象是否为引用。
|
|
1270
|
+
*/
|
|
1271
|
+
__publicField(this, _a, true);
|
|
1272
|
+
/**
|
|
1273
|
+
* 原始值。
|
|
1274
|
+
*
|
|
1275
|
+
* 存储未经响应式处理的原始值。
|
|
1276
|
+
* 用于比较值是否发生变化。
|
|
1277
|
+
*
|
|
1278
|
+
* @private
|
|
1279
|
+
*/
|
|
1280
|
+
__publicField(this, "_rawValue");
|
|
1144
1281
|
this._rawValue = toRaw(value);
|
|
1145
1282
|
this._value = toReactive(value);
|
|
1146
1283
|
}
|
|
@@ -1261,6 +1398,7 @@ class MutableReactiveHandler extends BaseReactiveHandler {
|
|
|
1261
1398
|
value,
|
|
1262
1399
|
isRef(target) ? target : receiver
|
|
1263
1400
|
);
|
|
1401
|
+
__DEV__ && console.assert(target === toRaw(receiver));
|
|
1264
1402
|
if (target === toRaw(receiver)) {
|
|
1265
1403
|
if (!hadKey) {
|
|
1266
1404
|
PropertyReactivity.trigger(target, TriggerOpTypes.ADD, key, value);
|
|
@@ -1487,6 +1625,8 @@ function createInstrumentations() {
|
|
|
1487
1625
|
if (!hadKey) {
|
|
1488
1626
|
key = toRaw(key);
|
|
1489
1627
|
hadKey = has.call(target, key);
|
|
1628
|
+
} else if (__DEV__) {
|
|
1629
|
+
checkIdentityKeys(target, has, key);
|
|
1490
1630
|
}
|
|
1491
1631
|
const oldValue = get.call(target, key);
|
|
1492
1632
|
target.set(key, value);
|
|
@@ -1514,6 +1654,8 @@ function createInstrumentations() {
|
|
|
1514
1654
|
if (!hadKey) {
|
|
1515
1655
|
key = toRaw(key);
|
|
1516
1656
|
hadKey = has.call(target, key);
|
|
1657
|
+
} else if (__DEV__) {
|
|
1658
|
+
checkIdentityKeys(target, has, key);
|
|
1517
1659
|
}
|
|
1518
1660
|
const oldValue = get ? get.call(target, key) : void 0;
|
|
1519
1661
|
const result = target.delete(key);
|
|
@@ -1535,7 +1677,7 @@ function createInstrumentations() {
|
|
|
1535
1677
|
clear() {
|
|
1536
1678
|
const target = toRaw(this);
|
|
1537
1679
|
const hadItems = target.size !== 0;
|
|
1538
|
-
const oldTarget = void 0;
|
|
1680
|
+
const oldTarget = __DEV__ ? isMap(target) ? new Map(target) : new Set(target) : void 0;
|
|
1539
1681
|
const result = target.clear();
|
|
1540
1682
|
if (hadItems) {
|
|
1541
1683
|
PropertyReactivity.trigger(
|
|
@@ -1590,6 +1732,15 @@ function createIterableMethod(method) {
|
|
|
1590
1732
|
};
|
|
1591
1733
|
};
|
|
1592
1734
|
}
|
|
1735
|
+
function checkIdentityKeys(target, has, key) {
|
|
1736
|
+
const rawKey = toRaw(key);
|
|
1737
|
+
if (rawKey !== key && has.call(target, rawKey)) {
|
|
1738
|
+
const type = toRawType(target);
|
|
1739
|
+
warn(
|
|
1740
|
+
`响应式 ${type} 同时包含同一对象的原始版本和响应式版本${type === `Map` ? `作为键` : ``},这可能导致不一致。建议仅使用响应式版本。`
|
|
1741
|
+
);
|
|
1742
|
+
}
|
|
1743
|
+
}
|
|
1593
1744
|
const getProto = (v) => Reflect.getPrototypeOf(v);
|
|
1594
1745
|
function reactive(target) {
|
|
1595
1746
|
if (!isObject(target)) {
|
|
@@ -1628,8 +1779,21 @@ function isProxy(value) {
|
|
|
1628
1779
|
}
|
|
1629
1780
|
class ReactiveObject {
|
|
1630
1781
|
constructor() {
|
|
1631
|
-
|
|
1632
|
-
|
|
1782
|
+
/**
|
|
1783
|
+
* 副作用作用域
|
|
1784
|
+
*
|
|
1785
|
+
* 用于管理所有副作用的生命周期:
|
|
1786
|
+
* - 收集所有通过 effect() 方法创建的副作用
|
|
1787
|
+
* - 在类销毁时自动停止所有副作用
|
|
1788
|
+
* - 防止副作用在类销毁后继续执行,避免内存泄漏
|
|
1789
|
+
*
|
|
1790
|
+
* 私有属性,外部无法直接访问,只能通过 effect() 方法使用
|
|
1791
|
+
*/
|
|
1792
|
+
__publicField(this, "_effectScope", new EffectScope());
|
|
1793
|
+
/**
|
|
1794
|
+
* 销毁时需要执行的函数
|
|
1795
|
+
*/
|
|
1796
|
+
__publicField(this, "_destroyCallbacks", []);
|
|
1633
1797
|
}
|
|
1634
1798
|
/**
|
|
1635
1799
|
* 创建并运行副作用
|
|
@@ -1706,6 +1870,7 @@ class ReactiveObject {
|
|
|
1706
1870
|
this._effectScope = null;
|
|
1707
1871
|
}
|
|
1708
1872
|
}
|
|
1873
|
+
console.log("@feng3d/reactivity v1.0.12");
|
|
1709
1874
|
export {
|
|
1710
1875
|
EffectScope,
|
|
1711
1876
|
ReactiveObject,
|