@vue/reactivity 3.4.26 → 3.5.0-alpha.1

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.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @vue/reactivity v3.4.26
2
+ * @vue/reactivity v3.5.0-alpha.1
3
3
  * (c) 2018-present Yuxi (Evan) You and Vue contributors
4
4
  * @license MIT
5
5
  **/
@@ -10,8 +10,6 @@ function makeMap(str, expectsLowerCase) {
10
10
  return (val) => set.has(val);
11
11
  }
12
12
 
13
- const NOOP = () => {
14
- };
15
13
  const extend = Object.assign;
16
14
  const hasOwnProperty$1 = Object.prototype.hasOwnProperty;
17
15
  const hasOwn = (val, key) => hasOwnProperty$1.call(val, key);
@@ -38,11 +36,10 @@ const capitalize = cacheStringFunction((str) => {
38
36
  return str.charAt(0).toUpperCase() + str.slice(1);
39
37
  });
40
38
  const hasChanged = (value, oldValue) => !Object.is(value, oldValue);
41
- const def = (obj, key, value, writable = false) => {
39
+ const def = (obj, key, value) => {
42
40
  Object.defineProperty(obj, key, {
43
41
  configurable: true,
44
42
  enumerable: false,
45
- writable,
46
43
  value
47
44
  });
48
45
  };
@@ -133,156 +130,296 @@ class EffectScope {
133
130
  function effectScope(detached) {
134
131
  return new EffectScope(detached);
135
132
  }
136
- function recordEffectScope(effect, scope = activeEffectScope) {
137
- if (scope && scope.active) {
138
- scope.effects.push(effect);
139
- }
140
- }
141
133
  function getCurrentScope() {
142
134
  return activeEffectScope;
143
135
  }
144
- function onScopeDispose(fn) {
136
+ function onScopeDispose(fn, failSilently = false) {
145
137
  if (activeEffectScope) {
146
138
  activeEffectScope.cleanups.push(fn);
147
- } else {
139
+ } else if (!failSilently) {
148
140
  warn(
149
141
  `onScopeDispose() is called when there is no active effect scope to be associated with.`
150
142
  );
151
143
  }
152
144
  }
153
145
 
154
- let activeEffect;
146
+ let activeSub;
147
+ const EffectFlags = {
148
+ "ACTIVE": 1,
149
+ "1": "ACTIVE",
150
+ "RUNNING": 2,
151
+ "2": "RUNNING",
152
+ "TRACKING": 4,
153
+ "4": "TRACKING",
154
+ "NOTIFIED": 8,
155
+ "8": "NOTIFIED",
156
+ "DIRTY": 16,
157
+ "16": "DIRTY",
158
+ "ALLOW_RECURSE": 32,
159
+ "32": "ALLOW_RECURSE",
160
+ "NO_BATCH": 64,
161
+ "64": "NO_BATCH"
162
+ };
155
163
  class ReactiveEffect {
156
- constructor(fn, trigger, scheduler, scope) {
164
+ constructor(fn) {
157
165
  this.fn = fn;
158
- this.trigger = trigger;
159
- this.scheduler = scheduler;
160
- this.active = true;
161
- this.deps = [];
162
166
  /**
163
167
  * @internal
164
168
  */
165
- this._dirtyLevel = 4;
169
+ this.deps = void 0;
166
170
  /**
167
171
  * @internal
168
172
  */
169
- this._trackId = 0;
173
+ this.depsTail = void 0;
170
174
  /**
171
175
  * @internal
172
176
  */
173
- this._runnings = 0;
177
+ this.flags = 1 | 4;
174
178
  /**
175
179
  * @internal
176
180
  */
177
- this._shouldSchedule = false;
181
+ this.nextEffect = void 0;
178
182
  /**
179
183
  * @internal
180
184
  */
181
- this._depsLength = 0;
182
- recordEffectScope(this, scope);
183
- }
184
- get dirty() {
185
- if (this._dirtyLevel === 2 || this._dirtyLevel === 3) {
186
- this._dirtyLevel = 1;
187
- pauseTracking();
188
- for (let i = 0; i < this._depsLength; i++) {
189
- const dep = this.deps[i];
190
- if (dep.computed) {
191
- triggerComputed(dep.computed);
192
- if (this._dirtyLevel >= 4) {
193
- break;
194
- }
195
- }
196
- }
197
- if (this._dirtyLevel === 1) {
198
- this._dirtyLevel = 0;
199
- }
200
- resetTracking();
185
+ this.cleanup = void 0;
186
+ this.scheduler = void 0;
187
+ if (activeEffectScope && activeEffectScope.active) {
188
+ activeEffectScope.effects.push(this);
201
189
  }
202
- return this._dirtyLevel >= 4;
203
190
  }
204
- set dirty(v) {
205
- this._dirtyLevel = v ? 4 : 0;
191
+ /**
192
+ * @internal
193
+ */
194
+ notify() {
195
+ if (this.flags & 2 && !(this.flags & 32)) {
196
+ return;
197
+ }
198
+ if (this.flags & 64) {
199
+ return this.trigger();
200
+ }
201
+ if (!(this.flags & 8)) {
202
+ this.flags |= 8;
203
+ this.nextEffect = batchedEffect;
204
+ batchedEffect = this;
205
+ }
206
206
  }
207
207
  run() {
208
- this._dirtyLevel = 0;
209
- if (!this.active) {
208
+ if (!(this.flags & 1)) {
210
209
  return this.fn();
211
210
  }
212
- let lastShouldTrack = shouldTrack;
213
- let lastEffect = activeEffect;
211
+ this.flags |= 2;
212
+ cleanupEffect(this);
213
+ prepareDeps(this);
214
+ const prevEffect = activeSub;
215
+ const prevShouldTrack = shouldTrack;
216
+ activeSub = this;
217
+ shouldTrack = true;
214
218
  try {
215
- shouldTrack = true;
216
- activeEffect = this;
217
- this._runnings++;
218
- preCleanupEffect(this);
219
219
  return this.fn();
220
220
  } finally {
221
- postCleanupEffect(this);
222
- this._runnings--;
223
- activeEffect = lastEffect;
224
- shouldTrack = lastShouldTrack;
221
+ if (activeSub !== this) {
222
+ warn(
223
+ "Active effect was not restored correctly - this is likely a Vue internal bug."
224
+ );
225
+ }
226
+ cleanupDeps(this);
227
+ activeSub = prevEffect;
228
+ shouldTrack = prevShouldTrack;
229
+ this.flags &= ~2;
225
230
  }
226
231
  }
227
232
  stop() {
228
- if (this.active) {
229
- preCleanupEffect(this);
230
- postCleanupEffect(this);
233
+ if (this.flags & 1) {
234
+ for (let link = this.deps; link; link = link.nextDep) {
235
+ removeSub(link);
236
+ }
237
+ this.deps = this.depsTail = void 0;
238
+ cleanupEffect(this);
231
239
  this.onStop && this.onStop();
232
- this.active = false;
240
+ this.flags &= ~1;
241
+ }
242
+ }
243
+ trigger() {
244
+ if (this.scheduler) {
245
+ this.scheduler();
246
+ } else {
247
+ this.runIfDirty();
248
+ }
249
+ }
250
+ /**
251
+ * @internal
252
+ */
253
+ runIfDirty() {
254
+ if (isDirty(this)) {
255
+ this.run();
233
256
  }
234
257
  }
258
+ get dirty() {
259
+ return isDirty(this);
260
+ }
235
261
  }
236
- function triggerComputed(computed) {
237
- return computed.value;
262
+ let batchDepth = 0;
263
+ let batchedEffect;
264
+ function startBatch() {
265
+ batchDepth++;
238
266
  }
239
- function preCleanupEffect(effect2) {
240
- effect2._trackId++;
241
- effect2._depsLength = 0;
267
+ function endBatch() {
268
+ if (batchDepth > 1) {
269
+ batchDepth--;
270
+ return;
271
+ }
272
+ let error;
273
+ while (batchedEffect) {
274
+ let e = batchedEffect;
275
+ batchedEffect = void 0;
276
+ while (e) {
277
+ const next = e.nextEffect;
278
+ e.nextEffect = void 0;
279
+ e.flags &= ~8;
280
+ if (e.flags & 1) {
281
+ try {
282
+ e.trigger();
283
+ } catch (err) {
284
+ if (!error)
285
+ error = err;
286
+ }
287
+ }
288
+ e = next;
289
+ }
290
+ }
291
+ batchDepth--;
292
+ if (error)
293
+ throw error;
294
+ }
295
+ function prepareDeps(sub) {
296
+ for (let link = sub.deps; link; link = link.nextDep) {
297
+ link.version = -1;
298
+ link.prevActiveLink = link.dep.activeLink;
299
+ link.dep.activeLink = link;
300
+ }
301
+ }
302
+ function cleanupDeps(sub) {
303
+ let head;
304
+ let tail = sub.depsTail;
305
+ for (let link = tail; link; link = link.prevDep) {
306
+ if (link.version === -1) {
307
+ if (link === tail)
308
+ tail = link.prevDep;
309
+ removeSub(link);
310
+ removeDep(link);
311
+ } else {
312
+ head = link;
313
+ }
314
+ link.dep.activeLink = link.prevActiveLink;
315
+ link.prevActiveLink = void 0;
316
+ }
317
+ sub.deps = head;
318
+ sub.depsTail = tail;
242
319
  }
243
- function postCleanupEffect(effect2) {
244
- if (effect2.deps.length > effect2._depsLength) {
245
- for (let i = effect2._depsLength; i < effect2.deps.length; i++) {
246
- cleanupDepEffect(effect2.deps[i], effect2);
320
+ function isDirty(sub) {
321
+ for (let link = sub.deps; link; link = link.nextDep) {
322
+ if (link.dep.version !== link.version || link.dep.computed && refreshComputed(link.dep.computed) === false || link.dep.version !== link.version) {
323
+ return true;
247
324
  }
248
- effect2.deps.length = effect2._depsLength;
249
325
  }
326
+ if (sub._dirty) {
327
+ return true;
328
+ }
329
+ return false;
250
330
  }
251
- function cleanupDepEffect(dep, effect2) {
252
- const trackId = dep.get(effect2);
253
- if (trackId !== void 0 && effect2._trackId !== trackId) {
254
- dep.delete(effect2);
255
- if (dep.size === 0) {
256
- dep.cleanup();
331
+ function refreshComputed(computed) {
332
+ if (computed.flags & 2) {
333
+ return false;
334
+ }
335
+ if (computed.flags & 4 && !(computed.flags & 16)) {
336
+ return;
337
+ }
338
+ computed.flags &= ~16;
339
+ if (computed.globalVersion === globalVersion) {
340
+ return;
341
+ }
342
+ computed.globalVersion = globalVersion;
343
+ const dep = computed.dep;
344
+ computed.flags |= 2;
345
+ if (dep.version > 0 && !computed.isSSR && !isDirty(computed)) {
346
+ computed.flags &= ~2;
347
+ return;
348
+ }
349
+ const prevSub = activeSub;
350
+ const prevShouldTrack = shouldTrack;
351
+ activeSub = computed;
352
+ shouldTrack = true;
353
+ try {
354
+ prepareDeps(computed);
355
+ const value = computed.fn();
356
+ if (dep.version === 0 || hasChanged(value, computed._value)) {
357
+ computed._value = value;
358
+ dep.version++;
257
359
  }
360
+ } catch (err) {
361
+ dep.version++;
362
+ throw err;
363
+ } finally {
364
+ activeSub = prevSub;
365
+ shouldTrack = prevShouldTrack;
366
+ cleanupDeps(computed);
367
+ computed.flags &= ~2;
368
+ }
369
+ }
370
+ function removeSub(link) {
371
+ const { dep, prevSub, nextSub } = link;
372
+ if (prevSub) {
373
+ prevSub.nextSub = nextSub;
374
+ link.prevSub = void 0;
375
+ }
376
+ if (nextSub) {
377
+ nextSub.prevSub = prevSub;
378
+ link.nextSub = void 0;
379
+ }
380
+ if (dep.subs === link) {
381
+ dep.subs = prevSub;
382
+ }
383
+ if (!dep.subs && dep.computed) {
384
+ dep.computed.flags &= ~4;
385
+ for (let l = dep.computed.deps; l; l = l.nextDep) {
386
+ removeSub(l);
387
+ }
388
+ }
389
+ }
390
+ function removeDep(link) {
391
+ const { prevDep, nextDep } = link;
392
+ if (prevDep) {
393
+ prevDep.nextDep = nextDep;
394
+ link.prevDep = void 0;
395
+ }
396
+ if (nextDep) {
397
+ nextDep.prevDep = prevDep;
398
+ link.nextDep = void 0;
258
399
  }
259
400
  }
260
401
  function effect(fn, options) {
261
402
  if (fn.effect instanceof ReactiveEffect) {
262
403
  fn = fn.effect.fn;
263
404
  }
264
- const _effect = new ReactiveEffect(fn, NOOP, () => {
265
- if (_effect.dirty) {
266
- _effect.run();
267
- }
268
- });
405
+ const e = new ReactiveEffect(fn);
269
406
  if (options) {
270
- extend(_effect, options);
271
- if (options.scope)
272
- recordEffectScope(_effect, options.scope);
407
+ extend(e, options);
273
408
  }
274
- if (!options || !options.lazy) {
275
- _effect.run();
409
+ try {
410
+ e.run();
411
+ } catch (err) {
412
+ e.stop();
413
+ throw err;
276
414
  }
277
- const runner = _effect.run.bind(_effect);
278
- runner.effect = _effect;
415
+ const runner = e.run.bind(e);
416
+ runner.effect = e;
279
417
  return runner;
280
418
  }
281
419
  function stop(runner) {
282
420
  runner.effect.stop();
283
421
  }
284
422
  let shouldTrack = true;
285
- let pauseScheduleStack = 0;
286
423
  const trackStack = [];
287
424
  function pauseTracking() {
288
425
  trackStack.push(shouldTrack);
@@ -296,192 +433,423 @@ function resetTracking() {
296
433
  const last = trackStack.pop();
297
434
  shouldTrack = last === void 0 ? true : last;
298
435
  }
299
- function pauseScheduling() {
300
- pauseScheduleStack++;
301
- }
302
- function resetScheduling() {
303
- pauseScheduleStack--;
304
- while (!pauseScheduleStack && queueEffectSchedulers.length) {
305
- queueEffectSchedulers.shift()();
436
+ function onEffectCleanup(fn, failSilently = false) {
437
+ if (activeSub instanceof ReactiveEffect) {
438
+ activeSub.cleanup = fn;
439
+ } else if (!failSilently) {
440
+ warn(
441
+ `onEffectCleanup() was called when there was no active effect to associate with.`
442
+ );
306
443
  }
307
444
  }
308
- function trackEffect(effect2, dep, debuggerEventExtraInfo) {
309
- var _a;
310
- if (dep.get(effect2) !== effect2._trackId) {
311
- dep.set(effect2, effect2._trackId);
312
- const oldDep = effect2.deps[effect2._depsLength];
313
- if (oldDep !== dep) {
314
- if (oldDep) {
315
- cleanupDepEffect(oldDep, effect2);
316
- }
317
- effect2.deps[effect2._depsLength++] = dep;
318
- } else {
319
- effect2._depsLength++;
445
+ function cleanupEffect(e) {
446
+ const { cleanup } = e;
447
+ e.cleanup = void 0;
448
+ if (cleanup) {
449
+ const prevSub = activeSub;
450
+ activeSub = void 0;
451
+ try {
452
+ cleanup();
453
+ } finally {
454
+ activeSub = prevSub;
320
455
  }
456
+ }
457
+ }
458
+
459
+ let globalVersion = 0;
460
+ class Dep {
461
+ constructor(computed) {
462
+ this.computed = computed;
463
+ this.version = 0;
464
+ /**
465
+ * Link between this dep and the current active effect
466
+ */
467
+ this.activeLink = void 0;
468
+ /**
469
+ * Doubly linked list representing the subscribing effects (tail)
470
+ */
471
+ this.subs = void 0;
321
472
  {
322
- (_a = effect2.onTrack) == null ? void 0 : _a.call(effect2, extend({ effect: effect2 }, debuggerEventExtraInfo));
473
+ this.subsHead = void 0;
323
474
  }
324
475
  }
325
- }
326
- const queueEffectSchedulers = [];
327
- function triggerEffects(dep, dirtyLevel, debuggerEventExtraInfo) {
328
- var _a;
329
- pauseScheduling();
330
- for (const effect2 of dep.keys()) {
331
- let tracking;
332
- if (effect2._dirtyLevel < dirtyLevel && (tracking != null ? tracking : tracking = dep.get(effect2) === effect2._trackId)) {
333
- effect2._shouldSchedule || (effect2._shouldSchedule = effect2._dirtyLevel === 0);
334
- effect2._dirtyLevel = dirtyLevel;
476
+ track(debugInfo) {
477
+ if (!activeSub || !shouldTrack) {
478
+ return;
335
479
  }
336
- if (effect2._shouldSchedule && (tracking != null ? tracking : tracking = dep.get(effect2) === effect2._trackId)) {
337
- {
338
- (_a = effect2.onTrigger) == null ? void 0 : _a.call(effect2, extend({ effect: effect2 }, debuggerEventExtraInfo));
480
+ let link = this.activeLink;
481
+ if (link === void 0 || link.sub !== activeSub) {
482
+ link = this.activeLink = {
483
+ dep: this,
484
+ sub: activeSub,
485
+ version: this.version,
486
+ nextDep: void 0,
487
+ prevDep: void 0,
488
+ nextSub: void 0,
489
+ prevSub: void 0,
490
+ prevActiveLink: void 0
491
+ };
492
+ if (!activeSub.deps) {
493
+ activeSub.deps = activeSub.depsTail = link;
494
+ } else {
495
+ link.prevDep = activeSub.depsTail;
496
+ activeSub.depsTail.nextDep = link;
497
+ activeSub.depsTail = link;
498
+ }
499
+ if (activeSub.flags & 4) {
500
+ addSub(link);
501
+ }
502
+ } else if (link.version === -1) {
503
+ link.version = this.version;
504
+ if (link.nextDep) {
505
+ const next = link.nextDep;
506
+ next.prevDep = link.prevDep;
507
+ if (link.prevDep) {
508
+ link.prevDep.nextDep = next;
509
+ }
510
+ link.prevDep = activeSub.depsTail;
511
+ link.nextDep = void 0;
512
+ activeSub.depsTail.nextDep = link;
513
+ activeSub.depsTail = link;
514
+ if (activeSub.deps === link) {
515
+ activeSub.deps = next;
516
+ }
339
517
  }
340
- effect2.trigger();
341
- if ((!effect2._runnings || effect2.allowRecurse) && effect2._dirtyLevel !== 2) {
342
- effect2._shouldSchedule = false;
343
- if (effect2.scheduler) {
344
- queueEffectSchedulers.push(effect2.scheduler);
518
+ }
519
+ if (activeSub.onTrack) {
520
+ activeSub.onTrack(
521
+ extend(
522
+ {
523
+ effect: activeSub
524
+ },
525
+ debugInfo
526
+ )
527
+ );
528
+ }
529
+ return link;
530
+ }
531
+ trigger(debugInfo) {
532
+ this.version++;
533
+ globalVersion++;
534
+ this.notify(debugInfo);
535
+ }
536
+ notify(debugInfo) {
537
+ startBatch();
538
+ try {
539
+ if (true) {
540
+ for (let head = this.subsHead; head; head = head.nextSub) {
541
+ if (head.sub.onTrigger && !(head.sub.flags & 8)) {
542
+ head.sub.onTrigger(
543
+ extend(
544
+ {
545
+ effect: head.sub
546
+ },
547
+ debugInfo
548
+ )
549
+ );
550
+ }
345
551
  }
346
552
  }
553
+ for (let link = this.subs; link; link = link.prevSub) {
554
+ link.sub.notify();
555
+ }
556
+ } finally {
557
+ endBatch();
347
558
  }
348
559
  }
349
- resetScheduling();
350
560
  }
351
-
352
- const createDep = (cleanup, computed) => {
353
- const dep = /* @__PURE__ */ new Map();
354
- dep.cleanup = cleanup;
355
- dep.computed = computed;
356
- return dep;
357
- };
358
-
561
+ function addSub(link) {
562
+ const computed = link.dep.computed;
563
+ if (computed && !link.dep.subs) {
564
+ computed.flags |= 4 | 16;
565
+ for (let l = computed.deps; l; l = l.nextDep) {
566
+ addSub(l);
567
+ }
568
+ }
569
+ const currentTail = link.dep.subs;
570
+ if (currentTail !== link) {
571
+ link.prevSub = currentTail;
572
+ if (currentTail)
573
+ currentTail.nextSub = link;
574
+ }
575
+ if (link.dep.subsHead === void 0) {
576
+ link.dep.subsHead = link;
577
+ }
578
+ link.dep.subs = link;
579
+ }
359
580
  const targetMap = /* @__PURE__ */ new WeakMap();
360
- const ITERATE_KEY = Symbol("iterate" );
361
- const MAP_KEY_ITERATE_KEY = Symbol("Map key iterate" );
581
+ const ITERATE_KEY = Symbol("Object iterate" );
582
+ const MAP_KEY_ITERATE_KEY = Symbol("Map keys iterate" );
583
+ const ARRAY_ITERATE_KEY = Symbol("Array iterate" );
362
584
  function track(target, type, key) {
363
- if (shouldTrack && activeEffect) {
585
+ if (shouldTrack && activeSub) {
364
586
  let depsMap = targetMap.get(target);
365
587
  if (!depsMap) {
366
588
  targetMap.set(target, depsMap = /* @__PURE__ */ new Map());
367
589
  }
368
590
  let dep = depsMap.get(key);
369
591
  if (!dep) {
370
- depsMap.set(key, dep = createDep(() => depsMap.delete(key)));
592
+ depsMap.set(key, dep = new Dep());
371
593
  }
372
- trackEffect(
373
- activeEffect,
374
- dep,
375
- {
594
+ {
595
+ dep.track({
376
596
  target,
377
597
  type,
378
598
  key
379
- }
380
- );
599
+ });
600
+ }
381
601
  }
382
602
  }
383
603
  function trigger(target, type, key, newValue, oldValue, oldTarget) {
384
604
  const depsMap = targetMap.get(target);
385
605
  if (!depsMap) {
606
+ globalVersion++;
386
607
  return;
387
608
  }
388
609
  let deps = [];
389
610
  if (type === "clear") {
390
611
  deps = [...depsMap.values()];
391
- } else if (key === "length" && isArray(target)) {
392
- const newLength = Number(newValue);
393
- depsMap.forEach((dep, key2) => {
394
- if (key2 === "length" || !isSymbol(key2) && key2 >= newLength) {
395
- deps.push(dep);
396
- }
397
- });
398
612
  } else {
399
- if (key !== void 0) {
400
- deps.push(depsMap.get(key));
401
- }
402
- switch (type) {
403
- case "add":
404
- if (!isArray(target)) {
405
- deps.push(depsMap.get(ITERATE_KEY));
406
- if (isMap(target)) {
407
- deps.push(depsMap.get(MAP_KEY_ITERATE_KEY));
408
- }
409
- } else if (isIntegerKey(key)) {
410
- deps.push(depsMap.get("length"));
613
+ const targetIsArray = isArray(target);
614
+ const isArrayIndex = targetIsArray && isIntegerKey(key);
615
+ if (targetIsArray && key === "length") {
616
+ const newLength = Number(newValue);
617
+ depsMap.forEach((dep, key2) => {
618
+ if (key2 === "length" || key2 === ARRAY_ITERATE_KEY || !isSymbol(key2) && key2 >= newLength) {
619
+ deps.push(dep);
411
620
  }
412
- break;
413
- case "delete":
414
- if (!isArray(target)) {
415
- deps.push(depsMap.get(ITERATE_KEY));
621
+ });
622
+ } else {
623
+ const push = (dep) => dep && deps.push(dep);
624
+ if (key !== void 0) {
625
+ push(depsMap.get(key));
626
+ }
627
+ if (isArrayIndex) {
628
+ push(depsMap.get(ARRAY_ITERATE_KEY));
629
+ }
630
+ switch (type) {
631
+ case "add":
632
+ if (!targetIsArray) {
633
+ push(depsMap.get(ITERATE_KEY));
634
+ if (isMap(target)) {
635
+ push(depsMap.get(MAP_KEY_ITERATE_KEY));
636
+ }
637
+ } else if (isArrayIndex) {
638
+ push(depsMap.get("length"));
639
+ }
640
+ break;
641
+ case "delete":
642
+ if (!targetIsArray) {
643
+ push(depsMap.get(ITERATE_KEY));
644
+ if (isMap(target)) {
645
+ push(depsMap.get(MAP_KEY_ITERATE_KEY));
646
+ }
647
+ }
648
+ break;
649
+ case "set":
416
650
  if (isMap(target)) {
417
- deps.push(depsMap.get(MAP_KEY_ITERATE_KEY));
651
+ push(depsMap.get(ITERATE_KEY));
418
652
  }
419
- }
420
- break;
421
- case "set":
422
- if (isMap(target)) {
423
- deps.push(depsMap.get(ITERATE_KEY));
424
- }
425
- break;
653
+ break;
654
+ }
426
655
  }
427
656
  }
428
- pauseScheduling();
657
+ startBatch();
429
658
  for (const dep of deps) {
430
- if (dep) {
431
- triggerEffects(
432
- dep,
433
- 4,
434
- {
435
- target,
436
- type,
437
- key,
438
- newValue,
439
- oldValue,
440
- oldTarget
441
- }
442
- );
659
+ {
660
+ dep.trigger({
661
+ target,
662
+ type,
663
+ key,
664
+ newValue,
665
+ oldValue,
666
+ oldTarget
667
+ });
443
668
  }
444
669
  }
445
- resetScheduling();
670
+ endBatch();
446
671
  }
447
672
  function getDepFromReactive(object, key) {
448
- const depsMap = targetMap.get(object);
449
- return depsMap && depsMap.get(key);
673
+ var _a;
674
+ return (_a = targetMap.get(object)) == null ? void 0 : _a.get(key);
675
+ }
676
+
677
+ function reactiveReadArray(array) {
678
+ const raw = toRaw(array);
679
+ if (raw === array)
680
+ return raw;
681
+ track(raw, "iterate", ARRAY_ITERATE_KEY);
682
+ return isShallow(array) ? raw : raw.map(toReactive);
683
+ }
684
+ function shallowReadArray(arr) {
685
+ track(arr = toRaw(arr), "iterate", ARRAY_ITERATE_KEY);
686
+ return arr;
687
+ }
688
+ const arrayInstrumentations = {
689
+ __proto__: null,
690
+ [Symbol.iterator]() {
691
+ return iterator(this, Symbol.iterator, toReactive);
692
+ },
693
+ concat(...args) {
694
+ return reactiveReadArray(this).concat(
695
+ ...args.map((x) => reactiveReadArray(x))
696
+ );
697
+ },
698
+ entries() {
699
+ return iterator(this, "entries", (value) => {
700
+ value[1] = toReactive(value[1]);
701
+ return value;
702
+ });
703
+ },
704
+ every(fn, thisArg) {
705
+ return apply(this, "every", fn, thisArg);
706
+ },
707
+ filter(fn, thisArg) {
708
+ const result = apply(this, "filter", fn, thisArg);
709
+ return isProxy(this) && !isShallow(this) ? result.map(toReactive) : result;
710
+ },
711
+ find(fn, thisArg) {
712
+ const result = apply(this, "find", fn, thisArg);
713
+ return isProxy(this) && !isShallow(this) ? toReactive(result) : result;
714
+ },
715
+ findIndex(fn, thisArg) {
716
+ return apply(this, "findIndex", fn, thisArg);
717
+ },
718
+ findLast(fn, thisArg) {
719
+ const result = apply(this, "findLast", fn, thisArg);
720
+ return isProxy(this) && !isShallow(this) ? toReactive(result) : result;
721
+ },
722
+ findLastIndex(fn, thisArg) {
723
+ return apply(this, "findLastIndex", fn, thisArg);
724
+ },
725
+ // flat, flatMap could benefit from ARRAY_ITERATE but are not straight-forward to implement
726
+ forEach(fn, thisArg) {
727
+ return apply(this, "forEach", fn, thisArg);
728
+ },
729
+ includes(...args) {
730
+ return searchProxy(this, "includes", args);
731
+ },
732
+ indexOf(...args) {
733
+ return searchProxy(this, "indexOf", args);
734
+ },
735
+ join(separator) {
736
+ return reactiveReadArray(this).join(separator);
737
+ },
738
+ // keys() iterator only reads `length`, no optimisation required
739
+ lastIndexOf(...args) {
740
+ return searchProxy(this, "lastIndexOf", args);
741
+ },
742
+ map(fn, thisArg) {
743
+ return apply(this, "map", fn, thisArg);
744
+ },
745
+ pop() {
746
+ return noTracking(this, "pop");
747
+ },
748
+ push(...args) {
749
+ return noTracking(this, "push", args);
750
+ },
751
+ reduce(fn, ...args) {
752
+ return reduce(this, "reduce", fn, args);
753
+ },
754
+ reduceRight(fn, ...args) {
755
+ return reduce(this, "reduceRight", fn, args);
756
+ },
757
+ shift() {
758
+ return noTracking(this, "shift");
759
+ },
760
+ // slice could use ARRAY_ITERATE but also seems to beg for range tracking
761
+ some(fn, thisArg) {
762
+ return apply(this, "some", fn, thisArg);
763
+ },
764
+ splice(...args) {
765
+ return noTracking(this, "splice", args);
766
+ },
767
+ toReversed() {
768
+ return reactiveReadArray(this).toReversed();
769
+ },
770
+ toSorted(comparer) {
771
+ return reactiveReadArray(this).toSorted(comparer);
772
+ },
773
+ toSpliced(...args) {
774
+ return reactiveReadArray(this).toSpliced(...args);
775
+ },
776
+ unshift(...args) {
777
+ return noTracking(this, "unshift", args);
778
+ },
779
+ values() {
780
+ return iterator(this, "values", toReactive);
781
+ }
782
+ };
783
+ function iterator(self, method, wrapValue) {
784
+ const arr = shallowReadArray(self);
785
+ const iter = arr[method]();
786
+ if (arr !== self && !isShallow(self)) {
787
+ iter._next = iter.next;
788
+ iter.next = () => {
789
+ const result = iter._next();
790
+ if (result.value) {
791
+ result.value = wrapValue(result.value);
792
+ }
793
+ return result;
794
+ };
795
+ }
796
+ return iter;
797
+ }
798
+ function apply(self, method, fn, thisArg) {
799
+ const arr = shallowReadArray(self);
800
+ let wrappedFn = fn;
801
+ if (arr !== self) {
802
+ if (!isShallow(self)) {
803
+ wrappedFn = function(item, index) {
804
+ return fn.call(this, toReactive(item), index, self);
805
+ };
806
+ } else if (fn.length > 2) {
807
+ wrappedFn = function(item, index) {
808
+ return fn.call(this, item, index, self);
809
+ };
810
+ }
811
+ }
812
+ return arr[method](wrappedFn, thisArg);
813
+ }
814
+ function reduce(self, method, fn, args) {
815
+ const arr = shallowReadArray(self);
816
+ let wrappedFn = fn;
817
+ if (arr !== self) {
818
+ if (!isShallow(self)) {
819
+ wrappedFn = function(acc, item, index) {
820
+ return fn.call(this, acc, toReactive(item), index, self);
821
+ };
822
+ } else if (fn.length > 3) {
823
+ wrappedFn = function(acc, item, index) {
824
+ return fn.call(this, acc, item, index, self);
825
+ };
826
+ }
827
+ }
828
+ return arr[method](wrappedFn, ...args);
829
+ }
830
+ function searchProxy(self, method, args) {
831
+ const arr = toRaw(self);
832
+ track(arr, "iterate", ARRAY_ITERATE_KEY);
833
+ const res = arr[method](...args);
834
+ if ((res === -1 || res === false) && isProxy(args[0])) {
835
+ args[0] = toRaw(args[0]);
836
+ return arr[method](...args);
837
+ }
838
+ return res;
839
+ }
840
+ function noTracking(self, method, args = []) {
841
+ pauseTracking();
842
+ startBatch();
843
+ const res = toRaw(self)[method].apply(self, args);
844
+ endBatch();
845
+ resetTracking();
846
+ return res;
450
847
  }
451
848
 
452
849
  const isNonTrackableKeys = /* @__PURE__ */ makeMap(`__proto__,__v_isRef,__isVue`);
453
850
  const builtInSymbols = new Set(
454
851
  /* @__PURE__ */ Object.getOwnPropertyNames(Symbol).filter((key) => key !== "arguments" && key !== "caller").map((key) => Symbol[key]).filter(isSymbol)
455
852
  );
456
- const arrayInstrumentations = /* @__PURE__ */ createArrayInstrumentations();
457
- function createArrayInstrumentations() {
458
- const instrumentations = {};
459
- ["includes", "indexOf", "lastIndexOf"].forEach((key) => {
460
- instrumentations[key] = function(...args) {
461
- const arr = toRaw(this);
462
- for (let i = 0, l = this.length; i < l; i++) {
463
- track(arr, "get", i + "");
464
- }
465
- const res = arr[key](...args);
466
- if (res === -1 || res === false) {
467
- return arr[key](...args.map(toRaw));
468
- } else {
469
- return res;
470
- }
471
- };
472
- });
473
- ["push", "pop", "shift", "unshift", "splice"].forEach((key) => {
474
- instrumentations[key] = function(...args) {
475
- pauseTracking();
476
- pauseScheduling();
477
- const res = toRaw(this)[key].apply(this, args);
478
- resetScheduling();
479
- resetTracking();
480
- return res;
481
- };
482
- });
483
- return instrumentations;
484
- }
485
853
  function hasOwnProperty(key) {
486
854
  if (!isSymbol(key))
487
855
  key = String(key);
@@ -512,14 +880,22 @@ class BaseReactiveHandler {
512
880
  }
513
881
  const targetIsArray = isArray(target);
514
882
  if (!isReadonly2) {
515
- if (targetIsArray && hasOwn(arrayInstrumentations, key)) {
516
- return Reflect.get(arrayInstrumentations, key, receiver);
883
+ let fn;
884
+ if (targetIsArray && (fn = arrayInstrumentations[key])) {
885
+ return fn;
517
886
  }
518
887
  if (key === "hasOwnProperty") {
519
888
  return hasOwnProperty;
520
889
  }
521
890
  }
522
- const res = Reflect.get(target, key, receiver);
891
+ const res = Reflect.get(
892
+ target,
893
+ key,
894
+ // if this is a proxy wrapping a ref, return methods using the raw ref
895
+ // as receiver so that we don't have to call `toRaw` on the ref in all
896
+ // its class methods
897
+ isRef(target) ? target : receiver
898
+ );
523
899
  if (isSymbol(key) ? builtInSymbols.has(key) : isNonTrackableKeys(key)) {
524
900
  return res;
525
901
  }
@@ -1018,110 +1394,8 @@ function markRaw(value) {
1018
1394
  const toReactive = (value) => isObject(value) ? reactive(value) : value;
1019
1395
  const toReadonly = (value) => isObject(value) ? readonly(value) : value;
1020
1396
 
1021
- const COMPUTED_SIDE_EFFECT_WARN = `Computed is still dirty after getter evaluation, likely because a computed is mutating its own dependency in its getter. State mutations in computed getters should be avoided. Check the docs for more details: https://vuejs.org/guide/essentials/computed.html#getters-should-be-side-effect-free`;
1022
- class ComputedRefImpl {
1023
- constructor(getter, _setter, isReadonly, isSSR) {
1024
- this.getter = getter;
1025
- this._setter = _setter;
1026
- this.dep = void 0;
1027
- this.__v_isRef = true;
1028
- this["__v_isReadonly"] = false;
1029
- this.effect = new ReactiveEffect(
1030
- () => getter(this._value),
1031
- () => triggerRefValue(
1032
- this,
1033
- this.effect._dirtyLevel === 2 ? 2 : 3
1034
- )
1035
- );
1036
- this.effect.computed = this;
1037
- this.effect.active = this._cacheable = !isSSR;
1038
- this["__v_isReadonly"] = isReadonly;
1039
- }
1040
- get value() {
1041
- const self = toRaw(this);
1042
- if ((!self._cacheable || self.effect.dirty) && hasChanged(self._value, self._value = self.effect.run())) {
1043
- triggerRefValue(self, 4);
1044
- }
1045
- trackRefValue(self);
1046
- if (self.effect._dirtyLevel >= 2) {
1047
- if (this._warnRecursive) {
1048
- warn(COMPUTED_SIDE_EFFECT_WARN, `
1049
-
1050
- getter: `, this.getter);
1051
- }
1052
- triggerRefValue(self, 2);
1053
- }
1054
- return self._value;
1055
- }
1056
- set value(newValue) {
1057
- this._setter(newValue);
1058
- }
1059
- // #region polyfill _dirty for backward compatibility third party code for Vue <= 3.3.x
1060
- get _dirty() {
1061
- return this.effect.dirty;
1062
- }
1063
- set _dirty(v) {
1064
- this.effect.dirty = v;
1065
- }
1066
- // #endregion
1067
- }
1068
- function computed(getterOrOptions, debugOptions, isSSR = false) {
1069
- let getter;
1070
- let setter;
1071
- const onlyGetter = isFunction(getterOrOptions);
1072
- if (onlyGetter) {
1073
- getter = getterOrOptions;
1074
- setter = () => {
1075
- warn("Write operation failed: computed value is readonly");
1076
- } ;
1077
- } else {
1078
- getter = getterOrOptions.get;
1079
- setter = getterOrOptions.set;
1080
- }
1081
- const cRef = new ComputedRefImpl(getter, setter, onlyGetter || !setter, isSSR);
1082
- if (debugOptions && !isSSR) {
1083
- cRef.effect.onTrack = debugOptions.onTrack;
1084
- cRef.effect.onTrigger = debugOptions.onTrigger;
1085
- }
1086
- return cRef;
1087
- }
1088
-
1089
- function trackRefValue(ref2) {
1090
- var _a;
1091
- if (shouldTrack && activeEffect) {
1092
- ref2 = toRaw(ref2);
1093
- trackEffect(
1094
- activeEffect,
1095
- (_a = ref2.dep) != null ? _a : ref2.dep = createDep(
1096
- () => ref2.dep = void 0,
1097
- ref2 instanceof ComputedRefImpl ? ref2 : void 0
1098
- ),
1099
- {
1100
- target: ref2,
1101
- type: "get",
1102
- key: "value"
1103
- }
1104
- );
1105
- }
1106
- }
1107
- function triggerRefValue(ref2, dirtyLevel = 4, newVal) {
1108
- ref2 = toRaw(ref2);
1109
- const dep = ref2.dep;
1110
- if (dep) {
1111
- triggerEffects(
1112
- dep,
1113
- dirtyLevel,
1114
- {
1115
- target: ref2,
1116
- type: "set",
1117
- key: "value",
1118
- newValue: newVal
1119
- }
1120
- );
1121
- }
1122
- }
1123
1397
  function isRef(r) {
1124
- return !!(r && r.__v_isRef === true);
1398
+ return r ? r.__v_isRef === true : false;
1125
1399
  }
1126
1400
  function ref(value) {
1127
1401
  return createRef(value, false);
@@ -1138,27 +1412,49 @@ function createRef(rawValue, shallow) {
1138
1412
  class RefImpl {
1139
1413
  constructor(value, __v_isShallow) {
1140
1414
  this.__v_isShallow = __v_isShallow;
1141
- this.dep = void 0;
1415
+ this.dep = new Dep();
1142
1416
  this.__v_isRef = true;
1143
1417
  this._rawValue = __v_isShallow ? value : toRaw(value);
1144
1418
  this._value = __v_isShallow ? value : toReactive(value);
1145
1419
  }
1146
1420
  get value() {
1147
- trackRefValue(this);
1421
+ {
1422
+ this.dep.track({
1423
+ target: this,
1424
+ type: "get",
1425
+ key: "value"
1426
+ });
1427
+ }
1148
1428
  return this._value;
1149
1429
  }
1150
- set value(newVal) {
1151
- const useDirectValue = this.__v_isShallow || isShallow(newVal) || isReadonly(newVal);
1152
- newVal = useDirectValue ? newVal : toRaw(newVal);
1153
- if (hasChanged(newVal, this._rawValue)) {
1154
- this._rawValue = newVal;
1155
- this._value = useDirectValue ? newVal : toReactive(newVal);
1156
- triggerRefValue(this, 4, newVal);
1430
+ set value(newValue) {
1431
+ const oldValue = this._rawValue;
1432
+ const useDirectValue = this.__v_isShallow || isShallow(newValue) || isReadonly(newValue);
1433
+ newValue = useDirectValue ? newValue : toRaw(newValue);
1434
+ if (hasChanged(newValue, oldValue)) {
1435
+ this._rawValue = newValue;
1436
+ this._value = useDirectValue ? newValue : toReactive(newValue);
1437
+ {
1438
+ this.dep.trigger({
1439
+ target: this,
1440
+ type: "set",
1441
+ key: "value",
1442
+ newValue,
1443
+ oldValue
1444
+ });
1445
+ }
1157
1446
  }
1158
1447
  }
1159
1448
  }
1160
1449
  function triggerRef(ref2) {
1161
- triggerRefValue(ref2, 4, ref2.value );
1450
+ {
1451
+ ref2.dep.trigger({
1452
+ target: ref2,
1453
+ type: "set",
1454
+ key: "value",
1455
+ newValue: ref2._value
1456
+ });
1457
+ }
1162
1458
  }
1163
1459
  function unref(ref2) {
1164
1460
  return isRef(ref2) ? ref2.value : ref2;
@@ -1183,12 +1479,9 @@ function proxyRefs(objectWithRefs) {
1183
1479
  }
1184
1480
  class CustomRefImpl {
1185
1481
  constructor(factory) {
1186
- this.dep = void 0;
1187
1482
  this.__v_isRef = true;
1188
- const { get, set } = factory(
1189
- () => trackRefValue(this),
1190
- () => triggerRefValue(this)
1191
- );
1483
+ const dep = this.dep = new Dep();
1484
+ const { get, set } = factory(dep.track.bind(dep), dep.trigger.bind(dep));
1192
1485
  this._get = get;
1193
1486
  this._set = set;
1194
1487
  }
@@ -1256,7 +1549,89 @@ function propertyToRef(source, key, defaultValue) {
1256
1549
  return isRef(val) ? val : new ObjectRefImpl(source, key, defaultValue);
1257
1550
  }
1258
1551
 
1259
- const deferredComputed = computed;
1552
+ class ComputedRefImpl {
1553
+ constructor(fn, setter, isSSR) {
1554
+ this.fn = fn;
1555
+ this.setter = setter;
1556
+ /**
1557
+ * @internal
1558
+ */
1559
+ this._value = void 0;
1560
+ /**
1561
+ * @internal
1562
+ */
1563
+ this.dep = new Dep(this);
1564
+ /**
1565
+ * @internal
1566
+ */
1567
+ this.__v_isRef = true;
1568
+ // A computed is also a subscriber that tracks other deps
1569
+ /**
1570
+ * @internal
1571
+ */
1572
+ this.deps = void 0;
1573
+ /**
1574
+ * @internal
1575
+ */
1576
+ this.depsTail = void 0;
1577
+ /**
1578
+ * @internal
1579
+ */
1580
+ this.flags = 16;
1581
+ /**
1582
+ * @internal
1583
+ */
1584
+ this.globalVersion = globalVersion - 1;
1585
+ // for backwards compat
1586
+ this.effect = this;
1587
+ this.__v_isReadonly = !setter;
1588
+ this.isSSR = isSSR;
1589
+ }
1590
+ /**
1591
+ * @internal
1592
+ */
1593
+ notify() {
1594
+ if (activeSub !== this) {
1595
+ this.flags |= 16;
1596
+ this.dep.notify();
1597
+ }
1598
+ }
1599
+ get value() {
1600
+ const link = this.dep.track({
1601
+ target: this,
1602
+ type: "get",
1603
+ key: "value"
1604
+ }) ;
1605
+ refreshComputed(this);
1606
+ if (link) {
1607
+ link.version = this.dep.version;
1608
+ }
1609
+ return this._value;
1610
+ }
1611
+ set value(newValue) {
1612
+ if (this.setter) {
1613
+ this.setter(newValue);
1614
+ } else {
1615
+ warn("Write operation failed: computed value is readonly");
1616
+ }
1617
+ }
1618
+ }
1619
+ function computed(getterOrOptions, debugOptions, isSSR = false) {
1620
+ let getter;
1621
+ let setter;
1622
+ if (isFunction(getterOrOptions)) {
1623
+ getter = getterOrOptions;
1624
+ } else {
1625
+ getter = getterOrOptions.get;
1626
+ setter = getterOrOptions.set;
1627
+ }
1628
+ const cRef = new ComputedRefImpl(getter, setter, isSSR);
1629
+ if (debugOptions && !isSSR) {
1630
+ cRef.onTrack = debugOptions.onTrack;
1631
+ cRef.onTrigger = debugOptions.onTrigger;
1632
+ }
1633
+ return cRef;
1634
+ }
1260
1635
 
1261
1636
  const TrackOpTypes = {
1262
1637
  "GET": "get",
@@ -1277,4 +1652,4 @@ const ReactiveFlags = {
1277
1652
  "RAW": "__v_raw"
1278
1653
  };
1279
1654
 
1280
- export { EffectScope, ITERATE_KEY, ReactiveEffect, ReactiveFlags, TrackOpTypes, TriggerOpTypes, computed, customRef, deferredComputed, effect, effectScope, enableTracking, getCurrentScope, isProxy, isReactive, isReadonly, isRef, isShallow, markRaw, onScopeDispose, pauseScheduling, pauseTracking, proxyRefs, reactive, readonly, ref, resetScheduling, resetTracking, shallowReactive, shallowReadonly, shallowRef, stop, toRaw, toRef, toRefs, toValue, track, trigger, triggerRef, unref };
1655
+ export { ARRAY_ITERATE_KEY, EffectFlags, EffectScope, ITERATE_KEY, MAP_KEY_ITERATE_KEY, ReactiveEffect, ReactiveFlags, TrackOpTypes, TriggerOpTypes, computed, customRef, effect, effectScope, enableTracking, getCurrentScope, isProxy, isReactive, isReadonly, isRef, isShallow, markRaw, onEffectCleanup, onScopeDispose, pauseTracking, proxyRefs, reactive, reactiveReadArray, readonly, ref, resetTracking, shallowReactive, shallowReadArray, shallowReadonly, shallowRef, stop, toRaw, toReactive, toReadonly, toRef, toRefs, toValue, track, trigger, triggerRef, unref };