@vue/runtime-dom 3.3.7 → 3.4.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.
@@ -357,117 +357,120 @@ var VueRuntimeDOM = (function (exports) {
357
357
  }
358
358
  }
359
359
 
360
- const createDep = (effects) => {
361
- const dep = new Set(effects);
362
- dep.w = 0;
363
- dep.n = 0;
364
- return dep;
365
- };
366
- const wasTracked = (dep) => (dep.w & trackOpBit) > 0;
367
- const newTracked = (dep) => (dep.n & trackOpBit) > 0;
368
- const initDepMarkers = ({ deps }) => {
369
- if (deps.length) {
370
- for (let i = 0; i < deps.length; i++) {
371
- deps[i].w |= trackOpBit;
372
- }
373
- }
374
- };
375
- const finalizeDepMarkers = (effect) => {
376
- const { deps } = effect;
377
- if (deps.length) {
378
- let ptr = 0;
379
- for (let i = 0; i < deps.length; i++) {
380
- const dep = deps[i];
381
- if (wasTracked(dep) && !newTracked(dep)) {
382
- dep.delete(effect);
383
- } else {
384
- deps[ptr++] = dep;
385
- }
386
- dep.w &= ~trackOpBit;
387
- dep.n &= ~trackOpBit;
388
- }
389
- deps.length = ptr;
390
- }
391
- };
392
-
393
- const targetMap = /* @__PURE__ */ new WeakMap();
394
- let effectTrackDepth = 0;
395
- let trackOpBit = 1;
396
- const maxMarkerBits = 30;
397
360
  let activeEffect;
398
- const ITERATE_KEY = Symbol("iterate" );
399
- const MAP_KEY_ITERATE_KEY = Symbol("Map key iterate" );
400
361
  class ReactiveEffect {
401
- constructor(fn, scheduler = null, scope) {
362
+ constructor(fn, trigger, scheduler, scope) {
402
363
  this.fn = fn;
364
+ this.trigger = trigger;
403
365
  this.scheduler = scheduler;
404
366
  this.active = true;
405
367
  this.deps = [];
406
- this.parent = void 0;
368
+ /**
369
+ * @internal
370
+ */
371
+ this._dirtyLevel = 3;
372
+ /**
373
+ * @internal
374
+ */
375
+ this._trackId = 0;
376
+ /**
377
+ * @internal
378
+ */
379
+ this._runnings = 0;
380
+ /**
381
+ * @internal
382
+ */
383
+ this._queryings = 0;
384
+ /**
385
+ * @internal
386
+ */
387
+ this._depsLength = 0;
407
388
  recordEffectScope(this, scope);
408
389
  }
390
+ get dirty() {
391
+ if (this._dirtyLevel === 1) {
392
+ this._dirtyLevel = 0;
393
+ this._queryings++;
394
+ pauseTracking();
395
+ for (const dep of this.deps) {
396
+ if (dep.computed) {
397
+ triggerComputed(dep.computed);
398
+ if (this._dirtyLevel >= 2) {
399
+ break;
400
+ }
401
+ }
402
+ }
403
+ resetTracking();
404
+ this._queryings--;
405
+ }
406
+ return this._dirtyLevel >= 2;
407
+ }
408
+ set dirty(v) {
409
+ this._dirtyLevel = v ? 3 : 0;
410
+ }
409
411
  run() {
412
+ this._dirtyLevel = 0;
410
413
  if (!this.active) {
411
414
  return this.fn();
412
415
  }
413
- let parent = activeEffect;
414
416
  let lastShouldTrack = shouldTrack;
415
- while (parent) {
416
- if (parent === this) {
417
- return;
418
- }
419
- parent = parent.parent;
420
- }
417
+ let lastEffect = activeEffect;
421
418
  try {
422
- this.parent = activeEffect;
423
- activeEffect = this;
424
419
  shouldTrack = true;
425
- trackOpBit = 1 << ++effectTrackDepth;
426
- if (effectTrackDepth <= maxMarkerBits) {
427
- initDepMarkers(this);
428
- } else {
429
- cleanupEffect(this);
430
- }
420
+ activeEffect = this;
421
+ this._runnings++;
422
+ preCleanupEffect(this);
431
423
  return this.fn();
432
424
  } finally {
433
- if (effectTrackDepth <= maxMarkerBits) {
434
- finalizeDepMarkers(this);
435
- }
436
- trackOpBit = 1 << --effectTrackDepth;
437
- activeEffect = this.parent;
425
+ postCleanupEffect(this);
426
+ this._runnings--;
427
+ activeEffect = lastEffect;
438
428
  shouldTrack = lastShouldTrack;
439
- this.parent = void 0;
440
- if (this.deferStop) {
441
- this.stop();
442
- }
443
429
  }
444
430
  }
445
431
  stop() {
446
- if (activeEffect === this) {
447
- this.deferStop = true;
448
- } else if (this.active) {
449
- cleanupEffect(this);
450
- if (this.onStop) {
451
- this.onStop();
452
- }
432
+ var _a;
433
+ if (this.active) {
434
+ preCleanupEffect(this);
435
+ postCleanupEffect(this);
436
+ (_a = this.onStop) == null ? void 0 : _a.call(this);
453
437
  this.active = false;
454
438
  }
455
439
  }
456
440
  }
457
- function cleanupEffect(effect2) {
458
- const { deps } = effect2;
459
- if (deps.length) {
460
- for (let i = 0; i < deps.length; i++) {
461
- deps[i].delete(effect2);
441
+ function triggerComputed(computed) {
442
+ return computed.value;
443
+ }
444
+ function preCleanupEffect(effect2) {
445
+ effect2._trackId++;
446
+ effect2._depsLength = 0;
447
+ }
448
+ function postCleanupEffect(effect2) {
449
+ if (effect2.deps && effect2.deps.length > effect2._depsLength) {
450
+ for (let i = effect2._depsLength; i < effect2.deps.length; i++) {
451
+ cleanupDepEffect(effect2.deps[i], effect2);
452
+ }
453
+ effect2.deps.length = effect2._depsLength;
454
+ }
455
+ }
456
+ function cleanupDepEffect(dep, effect2) {
457
+ const trackId = dep.get(effect2);
458
+ if (trackId !== void 0 && effect2._trackId !== trackId) {
459
+ dep.delete(effect2);
460
+ if (dep.size === 0) {
461
+ dep.cleanup();
462
462
  }
463
- deps.length = 0;
464
463
  }
465
464
  }
466
465
  function effect(fn, options) {
467
466
  if (fn.effect instanceof ReactiveEffect) {
468
467
  fn = fn.effect.fn;
469
468
  }
470
- const _effect = new ReactiveEffect(fn);
469
+ const _effect = new ReactiveEffect(fn, NOOP, () => {
470
+ if (_effect.dirty) {
471
+ _effect.run();
472
+ }
473
+ });
471
474
  if (options) {
472
475
  extend(_effect, options);
473
476
  if (options.scope)
@@ -484,6 +487,7 @@ var VueRuntimeDOM = (function (exports) {
484
487
  runner.effect.stop();
485
488
  }
486
489
  let shouldTrack = true;
490
+ let pauseScheduleStack = 0;
487
491
  const trackStack = [];
488
492
  function pauseTracking() {
489
493
  trackStack.push(shouldTrack);
@@ -493,6 +497,68 @@ var VueRuntimeDOM = (function (exports) {
493
497
  const last = trackStack.pop();
494
498
  shouldTrack = last === void 0 ? true : last;
495
499
  }
500
+ function pauseScheduling() {
501
+ pauseScheduleStack++;
502
+ }
503
+ function resetScheduling() {
504
+ pauseScheduleStack--;
505
+ while (!pauseScheduleStack && queueEffectSchedulers.length) {
506
+ queueEffectSchedulers.shift()();
507
+ }
508
+ }
509
+ function trackEffect(effect2, dep, debuggerEventExtraInfo) {
510
+ var _a;
511
+ if (dep.get(effect2) !== effect2._trackId) {
512
+ dep.set(effect2, effect2._trackId);
513
+ const oldDep = effect2.deps[effect2._depsLength];
514
+ if (oldDep !== dep) {
515
+ if (oldDep) {
516
+ cleanupDepEffect(oldDep, effect2);
517
+ }
518
+ effect2.deps[effect2._depsLength++] = dep;
519
+ } else {
520
+ effect2._depsLength++;
521
+ }
522
+ {
523
+ (_a = effect2.onTrack) == null ? void 0 : _a.call(effect2, extend({ effect: effect2 }, debuggerEventExtraInfo));
524
+ }
525
+ }
526
+ }
527
+ const queueEffectSchedulers = [];
528
+ function triggerEffects(dep, dirtyLevel, debuggerEventExtraInfo) {
529
+ var _a;
530
+ pauseScheduling();
531
+ for (const effect2 of dep.keys()) {
532
+ if (!effect2.allowRecurse && effect2._runnings) {
533
+ continue;
534
+ }
535
+ if (effect2._dirtyLevel < dirtyLevel && (!effect2._runnings || dirtyLevel !== 2)) {
536
+ const lastDirtyLevel = effect2._dirtyLevel;
537
+ effect2._dirtyLevel = dirtyLevel;
538
+ if (lastDirtyLevel === 0 && (!effect2._queryings || dirtyLevel !== 2)) {
539
+ {
540
+ (_a = effect2.onTrigger) == null ? void 0 : _a.call(effect2, extend({ effect: effect2 }, debuggerEventExtraInfo));
541
+ }
542
+ effect2.trigger();
543
+ if (effect2.scheduler) {
544
+ queueEffectSchedulers.push(effect2.scheduler);
545
+ }
546
+ }
547
+ }
548
+ }
549
+ resetScheduling();
550
+ }
551
+
552
+ const createDep = (cleanup, computed) => {
553
+ const dep = /* @__PURE__ */ new Map();
554
+ dep.cleanup = cleanup;
555
+ dep.computed = computed;
556
+ return dep;
557
+ };
558
+
559
+ const targetMap = /* @__PURE__ */ new WeakMap();
560
+ const ITERATE_KEY = Symbol("iterate" );
561
+ const MAP_KEY_ITERATE_KEY = Symbol("Map key iterate" );
496
562
  function track(target, type, key) {
497
563
  if (shouldTrack && activeEffect) {
498
564
  let depsMap = targetMap.get(target);
@@ -501,35 +567,17 @@ var VueRuntimeDOM = (function (exports) {
501
567
  }
502
568
  let dep = depsMap.get(key);
503
569
  if (!dep) {
504
- depsMap.set(key, dep = createDep());
505
- }
506
- const eventInfo = { effect: activeEffect, target, type, key } ;
507
- trackEffects(dep, eventInfo);
508
- }
509
- }
510
- function trackEffects(dep, debuggerEventExtraInfo) {
511
- let shouldTrack2 = false;
512
- if (effectTrackDepth <= maxMarkerBits) {
513
- if (!newTracked(dep)) {
514
- dep.n |= trackOpBit;
515
- shouldTrack2 = !wasTracked(dep);
516
- }
517
- } else {
518
- shouldTrack2 = !dep.has(activeEffect);
519
- }
520
- if (shouldTrack2) {
521
- dep.add(activeEffect);
522
- activeEffect.deps.push(dep);
523
- if (activeEffect.onTrack) {
524
- activeEffect.onTrack(
525
- extend(
526
- {
527
- effect: activeEffect
528
- },
529
- debuggerEventExtraInfo
530
- )
531
- );
570
+ depsMap.set(key, dep = createDep(() => depsMap.delete(key)));
532
571
  }
572
+ trackEffect(
573
+ activeEffect,
574
+ dep,
575
+ {
576
+ target,
577
+ type,
578
+ key
579
+ }
580
+ );
533
581
  }
534
582
  }
535
583
  function trigger(target, type, key, newValue, oldValue, oldTarget) {
@@ -577,49 +625,24 @@ var VueRuntimeDOM = (function (exports) {
577
625
  break;
578
626
  }
579
627
  }
580
- const eventInfo = { target, type, key, newValue, oldValue, oldTarget } ;
581
- if (deps.length === 1) {
582
- if (deps[0]) {
583
- {
584
- triggerEffects(deps[0], eventInfo);
585
- }
586
- }
587
- } else {
588
- const effects = [];
589
- for (const dep of deps) {
590
- if (dep) {
591
- effects.push(...dep);
592
- }
593
- }
594
- {
595
- triggerEffects(createDep(effects), eventInfo);
596
- }
597
- }
598
- }
599
- function triggerEffects(dep, debuggerEventExtraInfo) {
600
- const effects = isArray(dep) ? dep : [...dep];
601
- for (const effect2 of effects) {
602
- if (effect2.computed) {
603
- triggerEffect(effect2, debuggerEventExtraInfo);
604
- }
605
- }
606
- for (const effect2 of effects) {
607
- if (!effect2.computed) {
608
- triggerEffect(effect2, debuggerEventExtraInfo);
609
- }
610
- }
611
- }
612
- function triggerEffect(effect2, debuggerEventExtraInfo) {
613
- if (effect2 !== activeEffect || effect2.allowRecurse) {
614
- if (effect2.onTrigger) {
615
- effect2.onTrigger(extend({ effect: effect2 }, debuggerEventExtraInfo));
616
- }
617
- if (effect2.scheduler) {
618
- effect2.scheduler();
619
- } else {
620
- effect2.run();
628
+ pauseScheduling();
629
+ for (const dep of deps) {
630
+ if (dep) {
631
+ triggerEffects(
632
+ dep,
633
+ 3,
634
+ {
635
+ target,
636
+ type,
637
+ key,
638
+ newValue,
639
+ oldValue,
640
+ oldTarget
641
+ }
642
+ );
621
643
  }
622
644
  }
645
+ resetScheduling();
623
646
  }
624
647
  function getDepFromReactive(object, key) {
625
648
  var _a;
@@ -650,7 +673,9 @@ var VueRuntimeDOM = (function (exports) {
650
673
  ["push", "pop", "shift", "unshift", "splice"].forEach((key) => {
651
674
  instrumentations[key] = function(...args) {
652
675
  pauseTracking();
676
+ pauseScheduling();
653
677
  const res = toRaw(this)[key].apply(this, args);
678
+ resetScheduling();
654
679
  resetTracking();
655
680
  return res;
656
681
  };
@@ -1189,30 +1214,93 @@ var VueRuntimeDOM = (function (exports) {
1189
1214
  const toReactive = (value) => isObject(value) ? reactive(value) : value;
1190
1215
  const toReadonly = (value) => isObject(value) ? readonly(value) : value;
1191
1216
 
1217
+ class ComputedRefImpl {
1218
+ constructor(getter, _setter, isReadonly, isSSR) {
1219
+ this._setter = _setter;
1220
+ this.dep = void 0;
1221
+ this.__v_isRef = true;
1222
+ this["__v_isReadonly"] = false;
1223
+ this.effect = new ReactiveEffect(getter, () => {
1224
+ triggerRefValue(this, 1);
1225
+ });
1226
+ this.effect.computed = this;
1227
+ this.effect.active = this._cacheable = !isSSR;
1228
+ this["__v_isReadonly"] = isReadonly;
1229
+ }
1230
+ get value() {
1231
+ const self = toRaw(this);
1232
+ trackRefValue(self);
1233
+ if (!self._cacheable || self.effect.dirty) {
1234
+ if (hasChanged(self._value, self._value = self.effect.run())) {
1235
+ triggerRefValue(self, 2);
1236
+ }
1237
+ }
1238
+ return self._value;
1239
+ }
1240
+ set value(newValue) {
1241
+ this._setter(newValue);
1242
+ }
1243
+ // #region polyfill _dirty for backward compatibility third party code for Vue <= 3.3.x
1244
+ get _dirty() {
1245
+ return this.effect.dirty;
1246
+ }
1247
+ set _dirty(v) {
1248
+ this.effect.dirty = v;
1249
+ }
1250
+ // #endregion
1251
+ }
1252
+ function computed$1(getterOrOptions, debugOptions, isSSR = false) {
1253
+ let getter;
1254
+ let setter;
1255
+ const onlyGetter = isFunction(getterOrOptions);
1256
+ if (onlyGetter) {
1257
+ getter = getterOrOptions;
1258
+ setter = () => {
1259
+ console.warn("Write operation failed: computed value is readonly");
1260
+ } ;
1261
+ } else {
1262
+ getter = getterOrOptions.get;
1263
+ setter = getterOrOptions.set;
1264
+ }
1265
+ const cRef = new ComputedRefImpl(getter, setter, onlyGetter || !setter, isSSR);
1266
+ if (debugOptions && !isSSR) {
1267
+ cRef.effect.onTrack = debugOptions.onTrack;
1268
+ cRef.effect.onTrigger = debugOptions.onTrigger;
1269
+ }
1270
+ return cRef;
1271
+ }
1272
+
1192
1273
  function trackRefValue(ref2) {
1193
1274
  if (shouldTrack && activeEffect) {
1194
1275
  ref2 = toRaw(ref2);
1195
- {
1196
- trackEffects(ref2.dep || (ref2.dep = createDep()), {
1276
+ trackEffect(
1277
+ activeEffect,
1278
+ ref2.dep || (ref2.dep = createDep(
1279
+ () => ref2.dep = void 0,
1280
+ ref2 instanceof ComputedRefImpl ? ref2 : void 0
1281
+ )),
1282
+ {
1197
1283
  target: ref2,
1198
1284
  type: "get",
1199
1285
  key: "value"
1200
- });
1201
- }
1286
+ }
1287
+ );
1202
1288
  }
1203
1289
  }
1204
- function triggerRefValue(ref2, newVal) {
1290
+ function triggerRefValue(ref2, dirtyLevel = 3, newVal) {
1205
1291
  ref2 = toRaw(ref2);
1206
1292
  const dep = ref2.dep;
1207
1293
  if (dep) {
1208
- {
1209
- triggerEffects(dep, {
1294
+ triggerEffects(
1295
+ dep,
1296
+ dirtyLevel,
1297
+ {
1210
1298
  target: ref2,
1211
1299
  type: "set",
1212
1300
  key: "value",
1213
1301
  newValue: newVal
1214
- });
1215
- }
1302
+ }
1303
+ );
1216
1304
  }
1217
1305
  }
1218
1306
  function isRef(r) {
@@ -1248,12 +1336,12 @@ var VueRuntimeDOM = (function (exports) {
1248
1336
  if (hasChanged(newVal, this._rawValue)) {
1249
1337
  this._rawValue = newVal;
1250
1338
  this._value = useDirectValue ? newVal : toReactive(newVal);
1251
- triggerRefValue(this, newVal);
1339
+ triggerRefValue(this, 3, newVal);
1252
1340
  }
1253
1341
  }
1254
1342
  }
1255
1343
  function triggerRef(ref2) {
1256
- triggerRefValue(ref2, ref2.value );
1344
+ triggerRefValue(ref2, 3, ref2.value );
1257
1345
  }
1258
1346
  function unref(ref2) {
1259
1347
  return isRef(ref2) ? ref2.value : ref2;
@@ -1351,57 +1439,6 @@ var VueRuntimeDOM = (function (exports) {
1351
1439
  return isRef(val) ? val : new ObjectRefImpl(source, key, defaultValue);
1352
1440
  }
1353
1441
 
1354
- class ComputedRefImpl {
1355
- constructor(getter, _setter, isReadonly, isSSR) {
1356
- this._setter = _setter;
1357
- this.dep = void 0;
1358
- this.__v_isRef = true;
1359
- this["__v_isReadonly"] = false;
1360
- this._dirty = true;
1361
- this.effect = new ReactiveEffect(getter, () => {
1362
- if (!this._dirty) {
1363
- this._dirty = true;
1364
- triggerRefValue(this);
1365
- }
1366
- });
1367
- this.effect.computed = this;
1368
- this.effect.active = this._cacheable = !isSSR;
1369
- this["__v_isReadonly"] = isReadonly;
1370
- }
1371
- get value() {
1372
- const self = toRaw(this);
1373
- trackRefValue(self);
1374
- if (self._dirty || !self._cacheable) {
1375
- self._dirty = false;
1376
- self._value = self.effect.run();
1377
- }
1378
- return self._value;
1379
- }
1380
- set value(newValue) {
1381
- this._setter(newValue);
1382
- }
1383
- }
1384
- function computed$1(getterOrOptions, debugOptions, isSSR = false) {
1385
- let getter;
1386
- let setter;
1387
- const onlyGetter = isFunction(getterOrOptions);
1388
- if (onlyGetter) {
1389
- getter = getterOrOptions;
1390
- setter = () => {
1391
- console.warn("Write operation failed: computed value is readonly");
1392
- } ;
1393
- } else {
1394
- getter = getterOrOptions.get;
1395
- setter = getterOrOptions.set;
1396
- }
1397
- const cRef = new ComputedRefImpl(getter, setter, onlyGetter || !setter, isSSR);
1398
- if (debugOptions && !isSSR) {
1399
- cRef.effect.onTrack = debugOptions.onTrack;
1400
- cRef.effect.onTrigger = debugOptions.onTrigger;
1401
- }
1402
- return cRef;
1403
- }
1404
-
1405
1442
  const stack = [];
1406
1443
  function pushWarningContext(vnode) {
1407
1444
  stack.push(vnode);
@@ -1516,7 +1553,7 @@ var VueRuntimeDOM = (function (exports) {
1516
1553
  }
1517
1554
  }
1518
1555
 
1519
- const ErrorTypeStrings = {
1556
+ const ErrorTypeStrings$1 = {
1520
1557
  ["sp"]: "serverPrefetch hook",
1521
1558
  ["bc"]: "beforeCreate hook",
1522
1559
  ["c"]: "created hook",
@@ -1577,7 +1614,7 @@ var VueRuntimeDOM = (function (exports) {
1577
1614
  if (instance) {
1578
1615
  let cur = instance.parent;
1579
1616
  const exposedInstance = instance.proxy;
1580
- const errorInfo = ErrorTypeStrings[type] ;
1617
+ const errorInfo = ErrorTypeStrings$1[type] ;
1581
1618
  while (cur) {
1582
1619
  const errorCapturedHooks = cur.ec;
1583
1620
  if (errorCapturedHooks) {
@@ -1604,7 +1641,7 @@ var VueRuntimeDOM = (function (exports) {
1604
1641
  }
1605
1642
  function logError(err, type, contextVNode, throwInDev = true) {
1606
1643
  {
1607
- const info = ErrorTypeStrings[type];
1644
+ const info = ErrorTypeStrings$1[type];
1608
1645
  if (contextVNode) {
1609
1646
  pushWarningContext(contextVNode);
1610
1647
  }
@@ -1832,6 +1869,7 @@ var VueRuntimeDOM = (function (exports) {
1832
1869
  }
1833
1870
  instance.renderCache = [];
1834
1871
  isHmrUpdating = true;
1872
+ instance.effect.dirty = true;
1835
1873
  instance.update();
1836
1874
  isHmrUpdating = false;
1837
1875
  });
@@ -1859,6 +1897,7 @@ var VueRuntimeDOM = (function (exports) {
1859
1897
  instance.ceReload(newComp.styles);
1860
1898
  hmrDirtyComponents.delete(oldComp);
1861
1899
  } else if (instance.parent) {
1900
+ instance.parent.effect.dirty = true;
1862
1901
  queueJob(instance.parent.update);
1863
1902
  } else if (instance.appContext.reload) {
1864
1903
  instance.appContext.reload();
@@ -3043,8 +3082,15 @@ var VueRuntimeDOM = (function (exports) {
3043
3082
  }
3044
3083
  return doWatch(source, cb, options);
3045
3084
  }
3046
- function doWatch(source, cb, { immediate, deep, flush, onTrack, onTrigger } = EMPTY_OBJ) {
3085
+ function doWatch(source, cb, { immediate, deep, flush, once, onTrack, onTrigger } = EMPTY_OBJ) {
3047
3086
  var _a;
3087
+ if (cb && once) {
3088
+ const _cb = cb;
3089
+ cb = (...args) => {
3090
+ _cb(...args);
3091
+ unwatch();
3092
+ };
3093
+ }
3048
3094
  if (!cb) {
3049
3095
  if (immediate !== void 0) {
3050
3096
  warn(
@@ -3056,6 +3102,11 @@ var VueRuntimeDOM = (function (exports) {
3056
3102
  `watch() "deep" option is only respected when using the watch(source, callback, options?) signature.`
3057
3103
  );
3058
3104
  }
3105
+ if (once !== void 0) {
3106
+ warn(
3107
+ `watch() "once" option is only respected when using the watch(source, callback, options?) signature.`
3108
+ );
3109
+ }
3059
3110
  }
3060
3111
  const warnInvalidSource = (s) => {
3061
3112
  warn(
@@ -3123,7 +3174,7 @@ var VueRuntimeDOM = (function (exports) {
3123
3174
  };
3124
3175
  let oldValue = isMultiSource ? new Array(source.length).fill(INITIAL_WATCHER_VALUE) : INITIAL_WATCHER_VALUE;
3125
3176
  const job = () => {
3126
- if (!effect.active) {
3177
+ if (!effect.active || !effect.dirty) {
3127
3178
  return;
3128
3179
  }
3129
3180
  if (cb) {
@@ -3156,7 +3207,13 @@ var VueRuntimeDOM = (function (exports) {
3156
3207
  job.id = instance.uid;
3157
3208
  scheduler = () => queueJob(job);
3158
3209
  }
3159
- const effect = new ReactiveEffect(getter, scheduler);
3210
+ const effect = new ReactiveEffect(getter, NOOP, scheduler);
3211
+ const unwatch = () => {
3212
+ effect.stop();
3213
+ if (instance && instance.scope) {
3214
+ remove(instance.scope.effects, effect);
3215
+ }
3216
+ };
3160
3217
  {
3161
3218
  effect.onTrack = onTrack;
3162
3219
  effect.onTrigger = onTrigger;
@@ -3175,12 +3232,6 @@ var VueRuntimeDOM = (function (exports) {
3175
3232
  } else {
3176
3233
  effect.run();
3177
3234
  }
3178
- const unwatch = () => {
3179
- effect.stop();
3180
- if (instance && instance.scope) {
3181
- remove(instance.scope.effects, effect);
3182
- }
3183
- };
3184
3235
  return unwatch;
3185
3236
  }
3186
3237
  function instanceWatch(source, value, options) {
@@ -3410,6 +3461,7 @@ var VueRuntimeDOM = (function (exports) {
3410
3461
  leavingHooks.afterLeave = () => {
3411
3462
  state.isLeaving = false;
3412
3463
  if (instance.update.active !== false) {
3464
+ instance.effect.dirty = true;
3413
3465
  instance.update();
3414
3466
  }
3415
3467
  };
@@ -3745,6 +3797,7 @@ var VueRuntimeDOM = (function (exports) {
3745
3797
  load().then(() => {
3746
3798
  loaded.value = true;
3747
3799
  if (instance.parent && isKeepAlive(instance.parent.vnode)) {
3800
+ instance.parent.effect.dirty = true;
3748
3801
  queueJob(instance.parent.update);
3749
3802
  }
3750
3803
  }).catch((err) => {
@@ -4039,7 +4092,7 @@ var VueRuntimeDOM = (function (exports) {
4039
4092
  }
4040
4093
  return wrappedHook;
4041
4094
  } else {
4042
- const apiName = toHandlerKey(ErrorTypeStrings[type].replace(/ hook$/, ""));
4095
+ const apiName = toHandlerKey(ErrorTypeStrings$1[type].replace(/ hook$/, ""));
4043
4096
  warn(
4044
4097
  `${apiName} is called when there is no active component instance to be associated with. Lifecycle injection APIs can only be used during execution of setup().` + (` If you are using async setup(), make sure to register lifecycle hooks before the first await statement.` )
4045
4098
  );
@@ -4261,7 +4314,10 @@ If this is a native custom element, make sure to exclude it from component resol
4261
4314
  $root: (i) => getPublicInstance(i.root),
4262
4315
  $emit: (i) => i.emit,
4263
4316
  $options: (i) => resolveMergedOptions(i) ,
4264
- $forceUpdate: (i) => i.f || (i.f = () => queueJob(i.update)),
4317
+ $forceUpdate: (i) => i.f || (i.f = () => {
4318
+ i.effect.dirty = true;
4319
+ queueJob(i.update);
4320
+ }),
4265
4321
  $nextTick: (i) => i.n || (i.n = nextTick.bind(i.proxy)),
4266
4322
  $watch: (i) => instanceWatch.bind(i)
4267
4323
  })
@@ -7012,6 +7068,7 @@ If you want to remount the same app, move your app creation logic into a factory
7012
7068
  } else {
7013
7069
  instance.next = n2;
7014
7070
  invalidateJob(instance.update);
7071
+ instance.effect.dirty = true;
7015
7072
  instance.update();
7016
7073
  }
7017
7074
  } else {
@@ -7181,11 +7238,16 @@ If you want to remount the same app, move your app creation logic into a factory
7181
7238
  };
7182
7239
  const effect = instance.effect = new ReactiveEffect(
7183
7240
  componentUpdateFn,
7241
+ NOOP,
7184
7242
  () => queueJob(update),
7185
7243
  instance.scope
7186
7244
  // track it in component's effect scope
7187
7245
  );
7188
- const update = instance.update = () => effect.run();
7246
+ const update = instance.update = () => {
7247
+ if (effect.dirty) {
7248
+ effect.run();
7249
+ }
7250
+ };
7189
7251
  update.id = instance.uid;
7190
7252
  toggleRecurse(instance, true);
7191
7253
  {
@@ -9069,7 +9131,8 @@ Component that was made reactive: `,
9069
9131
  return true;
9070
9132
  }
9071
9133
 
9072
- const version = "3.3.7";
9134
+ const version = "3.4.0-alpha.1";
9135
+ const ErrorTypeStrings = ErrorTypeStrings$1 ;
9073
9136
  const ssrUtils = null;
9074
9137
  const resolveFilter = null;
9075
9138
  const compatUtils = null;
@@ -10547,6 +10610,7 @@ Component that was made reactive: `,
10547
10610
  exports.BaseTransitionPropsValidators = BaseTransitionPropsValidators;
10548
10611
  exports.Comment = Comment;
10549
10612
  exports.EffectScope = EffectScope;
10613
+ exports.ErrorTypeStrings = ErrorTypeStrings;
10550
10614
  exports.Fragment = Fragment;
10551
10615
  exports.KeepAlive = KeepAlive;
10552
10616
  exports.ReactiveEffect = ReactiveEffect;