@vue/reactivity 3.4.26 → 3.5.0-alpha.2

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,9 +1,9 @@
1
1
  /**
2
- * @vue/reactivity v3.4.26
2
+ * @vue/reactivity v3.5.0-alpha.2
3
3
  * (c) 2018-present Yuxi (Evan) You and Vue contributors
4
4
  * @license MIT
5
5
  **/
6
- import { NOOP, extend, isArray, isSymbol, isMap, isIntegerKey, hasOwn, hasChanged, isObject, makeMap, capitalize, toRawType, def, isFunction } from '@vue/shared';
6
+ import { hasChanged, extend, isArray, isIntegerKey, isSymbol, isMap, hasOwn, isObject, makeMap, capitalize, toRawType, def, isFunction } from '@vue/shared';
7
7
 
8
8
  function warn(msg, ...args) {
9
9
  console.warn(`[Vue warn] ${msg}`, ...args);
@@ -91,156 +91,296 @@ class EffectScope {
91
91
  function effectScope(detached) {
92
92
  return new EffectScope(detached);
93
93
  }
94
- function recordEffectScope(effect, scope = activeEffectScope) {
95
- if (scope && scope.active) {
96
- scope.effects.push(effect);
97
- }
98
- }
99
94
  function getCurrentScope() {
100
95
  return activeEffectScope;
101
96
  }
102
- function onScopeDispose(fn) {
97
+ function onScopeDispose(fn, failSilently = false) {
103
98
  if (activeEffectScope) {
104
99
  activeEffectScope.cleanups.push(fn);
105
- } else if (!!(process.env.NODE_ENV !== "production")) {
100
+ } else if (!!(process.env.NODE_ENV !== "production") && !failSilently) {
106
101
  warn(
107
102
  `onScopeDispose() is called when there is no active effect scope to be associated with.`
108
103
  );
109
104
  }
110
105
  }
111
106
 
112
- let activeEffect;
107
+ let activeSub;
108
+ const EffectFlags = {
109
+ "ACTIVE": 1,
110
+ "1": "ACTIVE",
111
+ "RUNNING": 2,
112
+ "2": "RUNNING",
113
+ "TRACKING": 4,
114
+ "4": "TRACKING",
115
+ "NOTIFIED": 8,
116
+ "8": "NOTIFIED",
117
+ "DIRTY": 16,
118
+ "16": "DIRTY",
119
+ "ALLOW_RECURSE": 32,
120
+ "32": "ALLOW_RECURSE",
121
+ "NO_BATCH": 64,
122
+ "64": "NO_BATCH"
123
+ };
113
124
  class ReactiveEffect {
114
- constructor(fn, trigger, scheduler, scope) {
125
+ constructor(fn) {
115
126
  this.fn = fn;
116
- this.trigger = trigger;
117
- this.scheduler = scheduler;
118
- this.active = true;
119
- this.deps = [];
120
127
  /**
121
128
  * @internal
122
129
  */
123
- this._dirtyLevel = 4;
130
+ this.deps = void 0;
124
131
  /**
125
132
  * @internal
126
133
  */
127
- this._trackId = 0;
134
+ this.depsTail = void 0;
128
135
  /**
129
136
  * @internal
130
137
  */
131
- this._runnings = 0;
138
+ this.flags = 1 | 4;
132
139
  /**
133
140
  * @internal
134
141
  */
135
- this._shouldSchedule = false;
142
+ this.nextEffect = void 0;
136
143
  /**
137
144
  * @internal
138
145
  */
139
- this._depsLength = 0;
140
- recordEffectScope(this, scope);
141
- }
142
- get dirty() {
143
- if (this._dirtyLevel === 2 || this._dirtyLevel === 3) {
144
- this._dirtyLevel = 1;
145
- pauseTracking();
146
- for (let i = 0; i < this._depsLength; i++) {
147
- const dep = this.deps[i];
148
- if (dep.computed) {
149
- triggerComputed(dep.computed);
150
- if (this._dirtyLevel >= 4) {
151
- break;
152
- }
153
- }
154
- }
155
- if (this._dirtyLevel === 1) {
156
- this._dirtyLevel = 0;
157
- }
158
- resetTracking();
146
+ this.cleanup = void 0;
147
+ this.scheduler = void 0;
148
+ if (activeEffectScope && activeEffectScope.active) {
149
+ activeEffectScope.effects.push(this);
159
150
  }
160
- return this._dirtyLevel >= 4;
161
151
  }
162
- set dirty(v) {
163
- this._dirtyLevel = v ? 4 : 0;
152
+ /**
153
+ * @internal
154
+ */
155
+ notify() {
156
+ if (this.flags & 2 && !(this.flags & 32)) {
157
+ return;
158
+ }
159
+ if (this.flags & 64) {
160
+ return this.trigger();
161
+ }
162
+ if (!(this.flags & 8)) {
163
+ this.flags |= 8;
164
+ this.nextEffect = batchedEffect;
165
+ batchedEffect = this;
166
+ }
164
167
  }
165
168
  run() {
166
- this._dirtyLevel = 0;
167
- if (!this.active) {
169
+ if (!(this.flags & 1)) {
168
170
  return this.fn();
169
171
  }
170
- let lastShouldTrack = shouldTrack;
171
- let lastEffect = activeEffect;
172
+ this.flags |= 2;
173
+ cleanupEffect(this);
174
+ prepareDeps(this);
175
+ const prevEffect = activeSub;
176
+ const prevShouldTrack = shouldTrack;
177
+ activeSub = this;
178
+ shouldTrack = true;
172
179
  try {
173
- shouldTrack = true;
174
- activeEffect = this;
175
- this._runnings++;
176
- preCleanupEffect(this);
177
180
  return this.fn();
178
181
  } finally {
179
- postCleanupEffect(this);
180
- this._runnings--;
181
- activeEffect = lastEffect;
182
- shouldTrack = lastShouldTrack;
182
+ if (!!(process.env.NODE_ENV !== "production") && activeSub !== this) {
183
+ warn(
184
+ "Active effect was not restored correctly - this is likely a Vue internal bug."
185
+ );
186
+ }
187
+ cleanupDeps(this);
188
+ activeSub = prevEffect;
189
+ shouldTrack = prevShouldTrack;
190
+ this.flags &= ~2;
183
191
  }
184
192
  }
185
193
  stop() {
186
- if (this.active) {
187
- preCleanupEffect(this);
188
- postCleanupEffect(this);
194
+ if (this.flags & 1) {
195
+ for (let link = this.deps; link; link = link.nextDep) {
196
+ removeSub(link);
197
+ }
198
+ this.deps = this.depsTail = void 0;
199
+ cleanupEffect(this);
189
200
  this.onStop && this.onStop();
190
- this.active = false;
201
+ this.flags &= ~1;
202
+ }
203
+ }
204
+ trigger() {
205
+ if (this.scheduler) {
206
+ this.scheduler();
207
+ } else {
208
+ this.runIfDirty();
209
+ }
210
+ }
211
+ /**
212
+ * @internal
213
+ */
214
+ runIfDirty() {
215
+ if (isDirty(this)) {
216
+ this.run();
191
217
  }
192
218
  }
219
+ get dirty() {
220
+ return isDirty(this);
221
+ }
193
222
  }
194
- function triggerComputed(computed) {
195
- return computed.value;
223
+ let batchDepth = 0;
224
+ let batchedEffect;
225
+ function startBatch() {
226
+ batchDepth++;
196
227
  }
197
- function preCleanupEffect(effect2) {
198
- effect2._trackId++;
199
- effect2._depsLength = 0;
228
+ function endBatch() {
229
+ if (batchDepth > 1) {
230
+ batchDepth--;
231
+ return;
232
+ }
233
+ let error;
234
+ while (batchedEffect) {
235
+ let e = batchedEffect;
236
+ batchedEffect = void 0;
237
+ while (e) {
238
+ const next = e.nextEffect;
239
+ e.nextEffect = void 0;
240
+ e.flags &= ~8;
241
+ if (e.flags & 1) {
242
+ try {
243
+ e.trigger();
244
+ } catch (err) {
245
+ if (!error)
246
+ error = err;
247
+ }
248
+ }
249
+ e = next;
250
+ }
251
+ }
252
+ batchDepth--;
253
+ if (error)
254
+ throw error;
255
+ }
256
+ function prepareDeps(sub) {
257
+ for (let link = sub.deps; link; link = link.nextDep) {
258
+ link.version = -1;
259
+ link.prevActiveLink = link.dep.activeLink;
260
+ link.dep.activeLink = link;
261
+ }
262
+ }
263
+ function cleanupDeps(sub) {
264
+ let head;
265
+ let tail = sub.depsTail;
266
+ for (let link = tail; link; link = link.prevDep) {
267
+ if (link.version === -1) {
268
+ if (link === tail)
269
+ tail = link.prevDep;
270
+ removeSub(link);
271
+ removeDep(link);
272
+ } else {
273
+ head = link;
274
+ }
275
+ link.dep.activeLink = link.prevActiveLink;
276
+ link.prevActiveLink = void 0;
277
+ }
278
+ sub.deps = head;
279
+ sub.depsTail = tail;
200
280
  }
201
- function postCleanupEffect(effect2) {
202
- if (effect2.deps.length > effect2._depsLength) {
203
- for (let i = effect2._depsLength; i < effect2.deps.length; i++) {
204
- cleanupDepEffect(effect2.deps[i], effect2);
281
+ function isDirty(sub) {
282
+ for (let link = sub.deps; link; link = link.nextDep) {
283
+ if (link.dep.version !== link.version || link.dep.computed && refreshComputed(link.dep.computed) === false || link.dep.version !== link.version) {
284
+ return true;
205
285
  }
206
- effect2.deps.length = effect2._depsLength;
207
286
  }
287
+ if (sub._dirty) {
288
+ return true;
289
+ }
290
+ return false;
208
291
  }
209
- function cleanupDepEffect(dep, effect2) {
210
- const trackId = dep.get(effect2);
211
- if (trackId !== void 0 && effect2._trackId !== trackId) {
212
- dep.delete(effect2);
213
- if (dep.size === 0) {
214
- dep.cleanup();
292
+ function refreshComputed(computed) {
293
+ if (computed.flags & 2) {
294
+ return false;
295
+ }
296
+ if (computed.flags & 4 && !(computed.flags & 16)) {
297
+ return;
298
+ }
299
+ computed.flags &= ~16;
300
+ if (computed.globalVersion === globalVersion) {
301
+ return;
302
+ }
303
+ computed.globalVersion = globalVersion;
304
+ const dep = computed.dep;
305
+ computed.flags |= 2;
306
+ if (dep.version > 0 && !computed.isSSR && !isDirty(computed)) {
307
+ computed.flags &= ~2;
308
+ return;
309
+ }
310
+ const prevSub = activeSub;
311
+ const prevShouldTrack = shouldTrack;
312
+ activeSub = computed;
313
+ shouldTrack = true;
314
+ try {
315
+ prepareDeps(computed);
316
+ const value = computed.fn();
317
+ if (dep.version === 0 || hasChanged(value, computed._value)) {
318
+ computed._value = value;
319
+ dep.version++;
320
+ }
321
+ } catch (err) {
322
+ dep.version++;
323
+ throw err;
324
+ } finally {
325
+ activeSub = prevSub;
326
+ shouldTrack = prevShouldTrack;
327
+ cleanupDeps(computed);
328
+ computed.flags &= ~2;
329
+ }
330
+ }
331
+ function removeSub(link) {
332
+ const { dep, prevSub, nextSub } = link;
333
+ if (prevSub) {
334
+ prevSub.nextSub = nextSub;
335
+ link.prevSub = void 0;
336
+ }
337
+ if (nextSub) {
338
+ nextSub.prevSub = prevSub;
339
+ link.nextSub = void 0;
340
+ }
341
+ if (dep.subs === link) {
342
+ dep.subs = prevSub;
343
+ }
344
+ if (!dep.subs && dep.computed) {
345
+ dep.computed.flags &= ~4;
346
+ for (let l = dep.computed.deps; l; l = l.nextDep) {
347
+ removeSub(l);
215
348
  }
216
349
  }
217
350
  }
351
+ function removeDep(link) {
352
+ const { prevDep, nextDep } = link;
353
+ if (prevDep) {
354
+ prevDep.nextDep = nextDep;
355
+ link.prevDep = void 0;
356
+ }
357
+ if (nextDep) {
358
+ nextDep.prevDep = prevDep;
359
+ link.nextDep = void 0;
360
+ }
361
+ }
218
362
  function effect(fn, options) {
219
363
  if (fn.effect instanceof ReactiveEffect) {
220
364
  fn = fn.effect.fn;
221
365
  }
222
- const _effect = new ReactiveEffect(fn, NOOP, () => {
223
- if (_effect.dirty) {
224
- _effect.run();
225
- }
226
- });
366
+ const e = new ReactiveEffect(fn);
227
367
  if (options) {
228
- extend(_effect, options);
229
- if (options.scope)
230
- recordEffectScope(_effect, options.scope);
368
+ extend(e, options);
231
369
  }
232
- if (!options || !options.lazy) {
233
- _effect.run();
370
+ try {
371
+ e.run();
372
+ } catch (err) {
373
+ e.stop();
374
+ throw err;
234
375
  }
235
- const runner = _effect.run.bind(_effect);
236
- runner.effect = _effect;
376
+ const runner = e.run.bind(e);
377
+ runner.effect = e;
237
378
  return runner;
238
379
  }
239
380
  function stop(runner) {
240
381
  runner.effect.stop();
241
382
  }
242
383
  let shouldTrack = true;
243
- let pauseScheduleStack = 0;
244
384
  const trackStack = [];
245
385
  function pauseTracking() {
246
386
  trackStack.push(shouldTrack);
@@ -254,192 +394,427 @@ function resetTracking() {
254
394
  const last = trackStack.pop();
255
395
  shouldTrack = last === void 0 ? true : last;
256
396
  }
257
- function pauseScheduling() {
258
- pauseScheduleStack++;
259
- }
260
- function resetScheduling() {
261
- pauseScheduleStack--;
262
- while (!pauseScheduleStack && queueEffectSchedulers.length) {
263
- queueEffectSchedulers.shift()();
397
+ function onEffectCleanup(fn, failSilently = false) {
398
+ if (activeSub instanceof ReactiveEffect) {
399
+ activeSub.cleanup = fn;
400
+ } else if (!!(process.env.NODE_ENV !== "production") && !failSilently) {
401
+ warn(
402
+ `onEffectCleanup() was called when there was no active effect to associate with.`
403
+ );
264
404
  }
265
405
  }
266
- function trackEffect(effect2, dep, debuggerEventExtraInfo) {
267
- var _a;
268
- if (dep.get(effect2) !== effect2._trackId) {
269
- dep.set(effect2, effect2._trackId);
270
- const oldDep = effect2.deps[effect2._depsLength];
271
- if (oldDep !== dep) {
272
- if (oldDep) {
273
- cleanupDepEffect(oldDep, effect2);
274
- }
275
- effect2.deps[effect2._depsLength++] = dep;
276
- } else {
277
- effect2._depsLength++;
406
+ function cleanupEffect(e) {
407
+ const { cleanup } = e;
408
+ e.cleanup = void 0;
409
+ if (cleanup) {
410
+ const prevSub = activeSub;
411
+ activeSub = void 0;
412
+ try {
413
+ cleanup();
414
+ } finally {
415
+ activeSub = prevSub;
278
416
  }
417
+ }
418
+ }
419
+
420
+ let globalVersion = 0;
421
+ class Dep {
422
+ constructor(computed) {
423
+ this.computed = computed;
424
+ this.version = 0;
425
+ /**
426
+ * Link between this dep and the current active effect
427
+ */
428
+ this.activeLink = void 0;
429
+ /**
430
+ * Doubly linked list representing the subscribing effects (tail)
431
+ */
432
+ this.subs = void 0;
279
433
  if (!!(process.env.NODE_ENV !== "production")) {
280
- (_a = effect2.onTrack) == null ? void 0 : _a.call(effect2, extend({ effect: effect2 }, debuggerEventExtraInfo));
434
+ this.subsHead = void 0;
281
435
  }
282
436
  }
283
- }
284
- const queueEffectSchedulers = [];
285
- function triggerEffects(dep, dirtyLevel, debuggerEventExtraInfo) {
286
- var _a;
287
- pauseScheduling();
288
- for (const effect2 of dep.keys()) {
289
- let tracking;
290
- if (effect2._dirtyLevel < dirtyLevel && (tracking != null ? tracking : tracking = dep.get(effect2) === effect2._trackId)) {
291
- effect2._shouldSchedule || (effect2._shouldSchedule = effect2._dirtyLevel === 0);
292
- effect2._dirtyLevel = dirtyLevel;
437
+ track(debugInfo) {
438
+ if (!activeSub || !shouldTrack) {
439
+ return;
293
440
  }
294
- if (effect2._shouldSchedule && (tracking != null ? tracking : tracking = dep.get(effect2) === effect2._trackId)) {
295
- if (!!(process.env.NODE_ENV !== "production")) {
296
- (_a = effect2.onTrigger) == null ? void 0 : _a.call(effect2, extend({ effect: effect2 }, debuggerEventExtraInfo));
441
+ let link = this.activeLink;
442
+ if (link === void 0 || link.sub !== activeSub) {
443
+ link = this.activeLink = {
444
+ dep: this,
445
+ sub: activeSub,
446
+ version: this.version,
447
+ nextDep: void 0,
448
+ prevDep: void 0,
449
+ nextSub: void 0,
450
+ prevSub: void 0,
451
+ prevActiveLink: void 0
452
+ };
453
+ if (!activeSub.deps) {
454
+ activeSub.deps = activeSub.depsTail = link;
455
+ } else {
456
+ link.prevDep = activeSub.depsTail;
457
+ activeSub.depsTail.nextDep = link;
458
+ activeSub.depsTail = link;
459
+ }
460
+ if (activeSub.flags & 4) {
461
+ addSub(link);
297
462
  }
298
- effect2.trigger();
299
- if ((!effect2._runnings || effect2.allowRecurse) && effect2._dirtyLevel !== 2) {
300
- effect2._shouldSchedule = false;
301
- if (effect2.scheduler) {
302
- queueEffectSchedulers.push(effect2.scheduler);
463
+ } else if (link.version === -1) {
464
+ link.version = this.version;
465
+ if (link.nextDep) {
466
+ const next = link.nextDep;
467
+ next.prevDep = link.prevDep;
468
+ if (link.prevDep) {
469
+ link.prevDep.nextDep = next;
470
+ }
471
+ link.prevDep = activeSub.depsTail;
472
+ link.nextDep = void 0;
473
+ activeSub.depsTail.nextDep = link;
474
+ activeSub.depsTail = link;
475
+ if (activeSub.deps === link) {
476
+ activeSub.deps = next;
477
+ }
478
+ }
479
+ }
480
+ if (!!(process.env.NODE_ENV !== "production") && activeSub.onTrack) {
481
+ activeSub.onTrack(
482
+ extend(
483
+ {
484
+ effect: activeSub
485
+ },
486
+ debugInfo
487
+ )
488
+ );
489
+ }
490
+ return link;
491
+ }
492
+ trigger(debugInfo) {
493
+ this.version++;
494
+ globalVersion++;
495
+ this.notify(debugInfo);
496
+ }
497
+ notify(debugInfo) {
498
+ startBatch();
499
+ try {
500
+ if (!!(process.env.NODE_ENV !== "production")) {
501
+ for (let head = this.subsHead; head; head = head.nextSub) {
502
+ if (!!(process.env.NODE_ENV !== "production") && head.sub.onTrigger && !(head.sub.flags & 8)) {
503
+ head.sub.onTrigger(
504
+ extend(
505
+ {
506
+ effect: head.sub
507
+ },
508
+ debugInfo
509
+ )
510
+ );
511
+ }
303
512
  }
304
513
  }
514
+ for (let link = this.subs; link; link = link.prevSub) {
515
+ link.sub.notify();
516
+ }
517
+ } finally {
518
+ endBatch();
305
519
  }
306
520
  }
307
- resetScheduling();
308
521
  }
309
-
310
- const createDep = (cleanup, computed) => {
311
- const dep = /* @__PURE__ */ new Map();
312
- dep.cleanup = cleanup;
313
- dep.computed = computed;
314
- return dep;
315
- };
316
-
522
+ function addSub(link) {
523
+ const computed = link.dep.computed;
524
+ if (computed && !link.dep.subs) {
525
+ computed.flags |= 4 | 16;
526
+ for (let l = computed.deps; l; l = l.nextDep) {
527
+ addSub(l);
528
+ }
529
+ }
530
+ const currentTail = link.dep.subs;
531
+ if (currentTail !== link) {
532
+ link.prevSub = currentTail;
533
+ if (currentTail)
534
+ currentTail.nextSub = link;
535
+ }
536
+ if (!!(process.env.NODE_ENV !== "production") && link.dep.subsHead === void 0) {
537
+ link.dep.subsHead = link;
538
+ }
539
+ link.dep.subs = link;
540
+ }
317
541
  const targetMap = /* @__PURE__ */ new WeakMap();
318
- const ITERATE_KEY = Symbol(!!(process.env.NODE_ENV !== "production") ? "iterate" : "");
319
- const MAP_KEY_ITERATE_KEY = Symbol(!!(process.env.NODE_ENV !== "production") ? "Map key iterate" : "");
542
+ const ITERATE_KEY = Symbol(!!(process.env.NODE_ENV !== "production") ? "Object iterate" : "");
543
+ const MAP_KEY_ITERATE_KEY = Symbol(!!(process.env.NODE_ENV !== "production") ? "Map keys iterate" : "");
544
+ const ARRAY_ITERATE_KEY = Symbol(!!(process.env.NODE_ENV !== "production") ? "Array iterate" : "");
320
545
  function track(target, type, key) {
321
- if (shouldTrack && activeEffect) {
546
+ if (shouldTrack && activeSub) {
322
547
  let depsMap = targetMap.get(target);
323
548
  if (!depsMap) {
324
549
  targetMap.set(target, depsMap = /* @__PURE__ */ new Map());
325
550
  }
326
551
  let dep = depsMap.get(key);
327
552
  if (!dep) {
328
- depsMap.set(key, dep = createDep(() => depsMap.delete(key)));
553
+ depsMap.set(key, dep = new Dep());
329
554
  }
330
- trackEffect(
331
- activeEffect,
332
- dep,
333
- !!(process.env.NODE_ENV !== "production") ? {
555
+ if (!!(process.env.NODE_ENV !== "production")) {
556
+ dep.track({
334
557
  target,
335
558
  type,
336
559
  key
337
- } : void 0
338
- );
560
+ });
561
+ } else {
562
+ dep.track();
563
+ }
339
564
  }
340
565
  }
341
566
  function trigger(target, type, key, newValue, oldValue, oldTarget) {
342
567
  const depsMap = targetMap.get(target);
343
568
  if (!depsMap) {
569
+ globalVersion++;
344
570
  return;
345
571
  }
346
572
  let deps = [];
347
573
  if (type === "clear") {
348
574
  deps = [...depsMap.values()];
349
- } else if (key === "length" && isArray(target)) {
350
- const newLength = Number(newValue);
351
- depsMap.forEach((dep, key2) => {
352
- if (key2 === "length" || !isSymbol(key2) && key2 >= newLength) {
353
- deps.push(dep);
354
- }
355
- });
356
575
  } else {
357
- if (key !== void 0) {
358
- deps.push(depsMap.get(key));
359
- }
360
- switch (type) {
361
- case "add":
362
- if (!isArray(target)) {
363
- deps.push(depsMap.get(ITERATE_KEY));
364
- if (isMap(target)) {
365
- deps.push(depsMap.get(MAP_KEY_ITERATE_KEY));
366
- }
367
- } else if (isIntegerKey(key)) {
368
- deps.push(depsMap.get("length"));
576
+ const targetIsArray = isArray(target);
577
+ const isArrayIndex = targetIsArray && isIntegerKey(key);
578
+ if (targetIsArray && key === "length") {
579
+ const newLength = Number(newValue);
580
+ depsMap.forEach((dep, key2) => {
581
+ if (key2 === "length" || key2 === ARRAY_ITERATE_KEY || !isSymbol(key2) && key2 >= newLength) {
582
+ deps.push(dep);
369
583
  }
370
- break;
371
- case "delete":
372
- if (!isArray(target)) {
373
- deps.push(depsMap.get(ITERATE_KEY));
584
+ });
585
+ } else {
586
+ const push = (dep) => dep && deps.push(dep);
587
+ if (key !== void 0) {
588
+ push(depsMap.get(key));
589
+ }
590
+ if (isArrayIndex) {
591
+ push(depsMap.get(ARRAY_ITERATE_KEY));
592
+ }
593
+ switch (type) {
594
+ case "add":
595
+ if (!targetIsArray) {
596
+ push(depsMap.get(ITERATE_KEY));
597
+ if (isMap(target)) {
598
+ push(depsMap.get(MAP_KEY_ITERATE_KEY));
599
+ }
600
+ } else if (isArrayIndex) {
601
+ push(depsMap.get("length"));
602
+ }
603
+ break;
604
+ case "delete":
605
+ if (!targetIsArray) {
606
+ push(depsMap.get(ITERATE_KEY));
607
+ if (isMap(target)) {
608
+ push(depsMap.get(MAP_KEY_ITERATE_KEY));
609
+ }
610
+ }
611
+ break;
612
+ case "set":
374
613
  if (isMap(target)) {
375
- deps.push(depsMap.get(MAP_KEY_ITERATE_KEY));
614
+ push(depsMap.get(ITERATE_KEY));
376
615
  }
377
- }
378
- break;
379
- case "set":
380
- if (isMap(target)) {
381
- deps.push(depsMap.get(ITERATE_KEY));
382
- }
383
- break;
616
+ break;
617
+ }
384
618
  }
385
619
  }
386
- pauseScheduling();
620
+ startBatch();
387
621
  for (const dep of deps) {
388
- if (dep) {
389
- triggerEffects(
390
- dep,
391
- 4,
392
- !!(process.env.NODE_ENV !== "production") ? {
393
- target,
394
- type,
395
- key,
396
- newValue,
397
- oldValue,
398
- oldTarget
399
- } : void 0
400
- );
622
+ if (!!(process.env.NODE_ENV !== "production")) {
623
+ dep.trigger({
624
+ target,
625
+ type,
626
+ key,
627
+ newValue,
628
+ oldValue,
629
+ oldTarget
630
+ });
631
+ } else {
632
+ dep.trigger();
401
633
  }
402
634
  }
403
- resetScheduling();
635
+ endBatch();
404
636
  }
405
637
  function getDepFromReactive(object, key) {
406
- const depsMap = targetMap.get(object);
407
- return depsMap && depsMap.get(key);
638
+ var _a;
639
+ return (_a = targetMap.get(object)) == null ? void 0 : _a.get(key);
640
+ }
641
+
642
+ function reactiveReadArray(array) {
643
+ const raw = toRaw(array);
644
+ if (raw === array)
645
+ return raw;
646
+ track(raw, "iterate", ARRAY_ITERATE_KEY);
647
+ return isShallow(array) ? raw : raw.map(toReactive);
648
+ }
649
+ function shallowReadArray(arr) {
650
+ track(arr = toRaw(arr), "iterate", ARRAY_ITERATE_KEY);
651
+ return arr;
652
+ }
653
+ const arrayInstrumentations = {
654
+ __proto__: null,
655
+ [Symbol.iterator]() {
656
+ return iterator(this, Symbol.iterator, toReactive);
657
+ },
658
+ concat(...args) {
659
+ return reactiveReadArray(this).concat(
660
+ ...args.map((x) => reactiveReadArray(x))
661
+ );
662
+ },
663
+ entries() {
664
+ return iterator(this, "entries", (value) => {
665
+ value[1] = toReactive(value[1]);
666
+ return value;
667
+ });
668
+ },
669
+ every(fn, thisArg) {
670
+ return apply(this, "every", fn, thisArg);
671
+ },
672
+ filter(fn, thisArg) {
673
+ const result = apply(this, "filter", fn, thisArg);
674
+ return isProxy(this) && !isShallow(this) ? result.map(toReactive) : result;
675
+ },
676
+ find(fn, thisArg) {
677
+ const result = apply(this, "find", fn, thisArg);
678
+ return isProxy(this) && !isShallow(this) ? toReactive(result) : result;
679
+ },
680
+ findIndex(fn, thisArg) {
681
+ return apply(this, "findIndex", fn, thisArg);
682
+ },
683
+ findLast(fn, thisArg) {
684
+ const result = apply(this, "findLast", fn, thisArg);
685
+ return isProxy(this) && !isShallow(this) ? toReactive(result) : result;
686
+ },
687
+ findLastIndex(fn, thisArg) {
688
+ return apply(this, "findLastIndex", fn, thisArg);
689
+ },
690
+ // flat, flatMap could benefit from ARRAY_ITERATE but are not straight-forward to implement
691
+ forEach(fn, thisArg) {
692
+ return apply(this, "forEach", fn, thisArg);
693
+ },
694
+ includes(...args) {
695
+ return searchProxy(this, "includes", args);
696
+ },
697
+ indexOf(...args) {
698
+ return searchProxy(this, "indexOf", args);
699
+ },
700
+ join(separator) {
701
+ return reactiveReadArray(this).join(separator);
702
+ },
703
+ // keys() iterator only reads `length`, no optimisation required
704
+ lastIndexOf(...args) {
705
+ return searchProxy(this, "lastIndexOf", args);
706
+ },
707
+ map(fn, thisArg) {
708
+ return apply(this, "map", fn, thisArg);
709
+ },
710
+ pop() {
711
+ return noTracking(this, "pop");
712
+ },
713
+ push(...args) {
714
+ return noTracking(this, "push", args);
715
+ },
716
+ reduce(fn, ...args) {
717
+ return reduce(this, "reduce", fn, args);
718
+ },
719
+ reduceRight(fn, ...args) {
720
+ return reduce(this, "reduceRight", fn, args);
721
+ },
722
+ shift() {
723
+ return noTracking(this, "shift");
724
+ },
725
+ // slice could use ARRAY_ITERATE but also seems to beg for range tracking
726
+ some(fn, thisArg) {
727
+ return apply(this, "some", fn, thisArg);
728
+ },
729
+ splice(...args) {
730
+ return noTracking(this, "splice", args);
731
+ },
732
+ toReversed() {
733
+ return reactiveReadArray(this).toReversed();
734
+ },
735
+ toSorted(comparer) {
736
+ return reactiveReadArray(this).toSorted(comparer);
737
+ },
738
+ toSpliced(...args) {
739
+ return reactiveReadArray(this).toSpliced(...args);
740
+ },
741
+ unshift(...args) {
742
+ return noTracking(this, "unshift", args);
743
+ },
744
+ values() {
745
+ return iterator(this, "values", toReactive);
746
+ }
747
+ };
748
+ function iterator(self, method, wrapValue) {
749
+ const arr = shallowReadArray(self);
750
+ const iter = arr[method]();
751
+ if (arr !== self && !isShallow(self)) {
752
+ iter._next = iter.next;
753
+ iter.next = () => {
754
+ const result = iter._next();
755
+ if (result.value) {
756
+ result.value = wrapValue(result.value);
757
+ }
758
+ return result;
759
+ };
760
+ }
761
+ return iter;
762
+ }
763
+ function apply(self, method, fn, thisArg) {
764
+ const arr = shallowReadArray(self);
765
+ let wrappedFn = fn;
766
+ if (arr !== self) {
767
+ if (!isShallow(self)) {
768
+ wrappedFn = function(item, index) {
769
+ return fn.call(this, toReactive(item), index, self);
770
+ };
771
+ } else if (fn.length > 2) {
772
+ wrappedFn = function(item, index) {
773
+ return fn.call(this, item, index, self);
774
+ };
775
+ }
776
+ }
777
+ return arr[method](wrappedFn, thisArg);
778
+ }
779
+ function reduce(self, method, fn, args) {
780
+ const arr = shallowReadArray(self);
781
+ let wrappedFn = fn;
782
+ if (arr !== self) {
783
+ if (!isShallow(self)) {
784
+ wrappedFn = function(acc, item, index) {
785
+ return fn.call(this, acc, toReactive(item), index, self);
786
+ };
787
+ } else if (fn.length > 3) {
788
+ wrappedFn = function(acc, item, index) {
789
+ return fn.call(this, acc, item, index, self);
790
+ };
791
+ }
792
+ }
793
+ return arr[method](wrappedFn, ...args);
794
+ }
795
+ function searchProxy(self, method, args) {
796
+ const arr = toRaw(self);
797
+ track(arr, "iterate", ARRAY_ITERATE_KEY);
798
+ const res = arr[method](...args);
799
+ if ((res === -1 || res === false) && isProxy(args[0])) {
800
+ args[0] = toRaw(args[0]);
801
+ return arr[method](...args);
802
+ }
803
+ return res;
804
+ }
805
+ function noTracking(self, method, args = []) {
806
+ pauseTracking();
807
+ startBatch();
808
+ const res = toRaw(self)[method].apply(self, args);
809
+ endBatch();
810
+ resetTracking();
811
+ return res;
408
812
  }
409
813
 
410
814
  const isNonTrackableKeys = /* @__PURE__ */ makeMap(`__proto__,__v_isRef,__isVue`);
411
815
  const builtInSymbols = new Set(
412
816
  /* @__PURE__ */ Object.getOwnPropertyNames(Symbol).filter((key) => key !== "arguments" && key !== "caller").map((key) => Symbol[key]).filter(isSymbol)
413
817
  );
414
- const arrayInstrumentations = /* @__PURE__ */ createArrayInstrumentations();
415
- function createArrayInstrumentations() {
416
- const instrumentations = {};
417
- ["includes", "indexOf", "lastIndexOf"].forEach((key) => {
418
- instrumentations[key] = function(...args) {
419
- const arr = toRaw(this);
420
- for (let i = 0, l = this.length; i < l; i++) {
421
- track(arr, "get", i + "");
422
- }
423
- const res = arr[key](...args);
424
- if (res === -1 || res === false) {
425
- return arr[key](...args.map(toRaw));
426
- } else {
427
- return res;
428
- }
429
- };
430
- });
431
- ["push", "pop", "shift", "unshift", "splice"].forEach((key) => {
432
- instrumentations[key] = function(...args) {
433
- pauseTracking();
434
- pauseScheduling();
435
- const res = toRaw(this)[key].apply(this, args);
436
- resetScheduling();
437
- resetTracking();
438
- return res;
439
- };
440
- });
441
- return instrumentations;
442
- }
443
818
  function hasOwnProperty(key) {
444
819
  if (!isSymbol(key))
445
820
  key = String(key);
@@ -470,14 +845,22 @@ class BaseReactiveHandler {
470
845
  }
471
846
  const targetIsArray = isArray(target);
472
847
  if (!isReadonly2) {
473
- if (targetIsArray && hasOwn(arrayInstrumentations, key)) {
474
- return Reflect.get(arrayInstrumentations, key, receiver);
848
+ let fn;
849
+ if (targetIsArray && (fn = arrayInstrumentations[key])) {
850
+ return fn;
475
851
  }
476
852
  if (key === "hasOwnProperty") {
477
853
  return hasOwnProperty;
478
854
  }
479
855
  }
480
- const res = Reflect.get(target, key, receiver);
856
+ const res = Reflect.get(
857
+ target,
858
+ key,
859
+ // if this is a proxy wrapping a ref, return methods using the raw ref
860
+ // as receiver so that we don't have to call `toRaw` on the ref in all
861
+ // its class methods
862
+ isRef(target) ? target : receiver
863
+ );
481
864
  if (isSymbol(key) ? builtInSymbols.has(key) : isNonTrackableKeys(key)) {
482
865
  return res;
483
866
  }
@@ -976,110 +1359,8 @@ function markRaw(value) {
976
1359
  const toReactive = (value) => isObject(value) ? reactive(value) : value;
977
1360
  const toReadonly = (value) => isObject(value) ? readonly(value) : value;
978
1361
 
979
- 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`;
980
- class ComputedRefImpl {
981
- constructor(getter, _setter, isReadonly, isSSR) {
982
- this.getter = getter;
983
- this._setter = _setter;
984
- this.dep = void 0;
985
- this.__v_isRef = true;
986
- this["__v_isReadonly"] = false;
987
- this.effect = new ReactiveEffect(
988
- () => getter(this._value),
989
- () => triggerRefValue(
990
- this,
991
- this.effect._dirtyLevel === 2 ? 2 : 3
992
- )
993
- );
994
- this.effect.computed = this;
995
- this.effect.active = this._cacheable = !isSSR;
996
- this["__v_isReadonly"] = isReadonly;
997
- }
998
- get value() {
999
- const self = toRaw(this);
1000
- if ((!self._cacheable || self.effect.dirty) && hasChanged(self._value, self._value = self.effect.run())) {
1001
- triggerRefValue(self, 4);
1002
- }
1003
- trackRefValue(self);
1004
- if (self.effect._dirtyLevel >= 2) {
1005
- if (!!(process.env.NODE_ENV !== "production") && this._warnRecursive) {
1006
- warn(COMPUTED_SIDE_EFFECT_WARN, `
1007
-
1008
- getter: `, this.getter);
1009
- }
1010
- triggerRefValue(self, 2);
1011
- }
1012
- return self._value;
1013
- }
1014
- set value(newValue) {
1015
- this._setter(newValue);
1016
- }
1017
- // #region polyfill _dirty for backward compatibility third party code for Vue <= 3.3.x
1018
- get _dirty() {
1019
- return this.effect.dirty;
1020
- }
1021
- set _dirty(v) {
1022
- this.effect.dirty = v;
1023
- }
1024
- // #endregion
1025
- }
1026
- function computed(getterOrOptions, debugOptions, isSSR = false) {
1027
- let getter;
1028
- let setter;
1029
- const onlyGetter = isFunction(getterOrOptions);
1030
- if (onlyGetter) {
1031
- getter = getterOrOptions;
1032
- setter = !!(process.env.NODE_ENV !== "production") ? () => {
1033
- warn("Write operation failed: computed value is readonly");
1034
- } : NOOP;
1035
- } else {
1036
- getter = getterOrOptions.get;
1037
- setter = getterOrOptions.set;
1038
- }
1039
- const cRef = new ComputedRefImpl(getter, setter, onlyGetter || !setter, isSSR);
1040
- if (!!(process.env.NODE_ENV !== "production") && debugOptions && !isSSR) {
1041
- cRef.effect.onTrack = debugOptions.onTrack;
1042
- cRef.effect.onTrigger = debugOptions.onTrigger;
1043
- }
1044
- return cRef;
1045
- }
1046
-
1047
- function trackRefValue(ref2) {
1048
- var _a;
1049
- if (shouldTrack && activeEffect) {
1050
- ref2 = toRaw(ref2);
1051
- trackEffect(
1052
- activeEffect,
1053
- (_a = ref2.dep) != null ? _a : ref2.dep = createDep(
1054
- () => ref2.dep = void 0,
1055
- ref2 instanceof ComputedRefImpl ? ref2 : void 0
1056
- ),
1057
- !!(process.env.NODE_ENV !== "production") ? {
1058
- target: ref2,
1059
- type: "get",
1060
- key: "value"
1061
- } : void 0
1062
- );
1063
- }
1064
- }
1065
- function triggerRefValue(ref2, dirtyLevel = 4, newVal) {
1066
- ref2 = toRaw(ref2);
1067
- const dep = ref2.dep;
1068
- if (dep) {
1069
- triggerEffects(
1070
- dep,
1071
- dirtyLevel,
1072
- !!(process.env.NODE_ENV !== "production") ? {
1073
- target: ref2,
1074
- type: "set",
1075
- key: "value",
1076
- newValue: newVal
1077
- } : void 0
1078
- );
1079
- }
1080
- }
1081
1362
  function isRef(r) {
1082
- return !!(r && r.__v_isRef === true);
1363
+ return r ? r.__v_isRef === true : false;
1083
1364
  }
1084
1365
  function ref(value) {
1085
1366
  return createRef(value, false);
@@ -1096,27 +1377,55 @@ function createRef(rawValue, shallow) {
1096
1377
  class RefImpl {
1097
1378
  constructor(value, __v_isShallow) {
1098
1379
  this.__v_isShallow = __v_isShallow;
1099
- this.dep = void 0;
1380
+ this.dep = new Dep();
1100
1381
  this.__v_isRef = true;
1101
1382
  this._rawValue = __v_isShallow ? value : toRaw(value);
1102
1383
  this._value = __v_isShallow ? value : toReactive(value);
1103
1384
  }
1104
1385
  get value() {
1105
- trackRefValue(this);
1386
+ if (!!(process.env.NODE_ENV !== "production")) {
1387
+ this.dep.track({
1388
+ target: this,
1389
+ type: "get",
1390
+ key: "value"
1391
+ });
1392
+ } else {
1393
+ this.dep.track();
1394
+ }
1106
1395
  return this._value;
1107
1396
  }
1108
- set value(newVal) {
1109
- const useDirectValue = this.__v_isShallow || isShallow(newVal) || isReadonly(newVal);
1110
- newVal = useDirectValue ? newVal : toRaw(newVal);
1111
- if (hasChanged(newVal, this._rawValue)) {
1112
- this._rawValue = newVal;
1113
- this._value = useDirectValue ? newVal : toReactive(newVal);
1114
- triggerRefValue(this, 4, newVal);
1397
+ set value(newValue) {
1398
+ const oldValue = this._rawValue;
1399
+ const useDirectValue = this.__v_isShallow || isShallow(newValue) || isReadonly(newValue);
1400
+ newValue = useDirectValue ? newValue : toRaw(newValue);
1401
+ if (hasChanged(newValue, oldValue)) {
1402
+ this._rawValue = newValue;
1403
+ this._value = useDirectValue ? newValue : toReactive(newValue);
1404
+ if (!!(process.env.NODE_ENV !== "production")) {
1405
+ this.dep.trigger({
1406
+ target: this,
1407
+ type: "set",
1408
+ key: "value",
1409
+ newValue,
1410
+ oldValue
1411
+ });
1412
+ } else {
1413
+ this.dep.trigger();
1414
+ }
1115
1415
  }
1116
1416
  }
1117
1417
  }
1118
1418
  function triggerRef(ref2) {
1119
- triggerRefValue(ref2, 4, !!(process.env.NODE_ENV !== "production") ? ref2.value : void 0);
1419
+ if (!!(process.env.NODE_ENV !== "production")) {
1420
+ ref2.dep.trigger({
1421
+ target: ref2,
1422
+ type: "set",
1423
+ key: "value",
1424
+ newValue: ref2._value
1425
+ });
1426
+ } else {
1427
+ ref2.dep.trigger();
1428
+ }
1120
1429
  }
1121
1430
  function unref(ref2) {
1122
1431
  return isRef(ref2) ? ref2.value : ref2;
@@ -1141,12 +1450,9 @@ function proxyRefs(objectWithRefs) {
1141
1450
  }
1142
1451
  class CustomRefImpl {
1143
1452
  constructor(factory) {
1144
- this.dep = void 0;
1145
1453
  this.__v_isRef = true;
1146
- const { get, set } = factory(
1147
- () => trackRefValue(this),
1148
- () => triggerRefValue(this)
1149
- );
1454
+ const dep = this.dep = new Dep();
1455
+ const { get, set } = factory(dep.track.bind(dep), dep.trigger.bind(dep));
1150
1456
  this._get = get;
1151
1457
  this._set = set;
1152
1458
  }
@@ -1214,7 +1520,89 @@ function propertyToRef(source, key, defaultValue) {
1214
1520
  return isRef(val) ? val : new ObjectRefImpl(source, key, defaultValue);
1215
1521
  }
1216
1522
 
1217
- const deferredComputed = computed;
1523
+ class ComputedRefImpl {
1524
+ constructor(fn, setter, isSSR) {
1525
+ this.fn = fn;
1526
+ this.setter = setter;
1527
+ /**
1528
+ * @internal
1529
+ */
1530
+ this._value = void 0;
1531
+ /**
1532
+ * @internal
1533
+ */
1534
+ this.dep = new Dep(this);
1535
+ /**
1536
+ * @internal
1537
+ */
1538
+ this.__v_isRef = true;
1539
+ // A computed is also a subscriber that tracks other deps
1540
+ /**
1541
+ * @internal
1542
+ */
1543
+ this.deps = void 0;
1544
+ /**
1545
+ * @internal
1546
+ */
1547
+ this.depsTail = void 0;
1548
+ /**
1549
+ * @internal
1550
+ */
1551
+ this.flags = 16;
1552
+ /**
1553
+ * @internal
1554
+ */
1555
+ this.globalVersion = globalVersion - 1;
1556
+ // for backwards compat
1557
+ this.effect = this;
1558
+ this.__v_isReadonly = !setter;
1559
+ this.isSSR = isSSR;
1560
+ }
1561
+ /**
1562
+ * @internal
1563
+ */
1564
+ notify() {
1565
+ if (activeSub !== this) {
1566
+ this.flags |= 16;
1567
+ this.dep.notify();
1568
+ } else if (!!(process.env.NODE_ENV !== "production")) ;
1569
+ }
1570
+ get value() {
1571
+ const link = !!(process.env.NODE_ENV !== "production") ? this.dep.track({
1572
+ target: this,
1573
+ type: "get",
1574
+ key: "value"
1575
+ }) : this.dep.track();
1576
+ refreshComputed(this);
1577
+ if (link) {
1578
+ link.version = this.dep.version;
1579
+ }
1580
+ return this._value;
1581
+ }
1582
+ set value(newValue) {
1583
+ if (this.setter) {
1584
+ this.setter(newValue);
1585
+ } else if (!!(process.env.NODE_ENV !== "production")) {
1586
+ warn("Write operation failed: computed value is readonly");
1587
+ }
1588
+ }
1589
+ }
1590
+ function computed(getterOrOptions, debugOptions, isSSR = false) {
1591
+ let getter;
1592
+ let setter;
1593
+ if (isFunction(getterOrOptions)) {
1594
+ getter = getterOrOptions;
1595
+ } else {
1596
+ getter = getterOrOptions.get;
1597
+ setter = getterOrOptions.set;
1598
+ }
1599
+ const cRef = new ComputedRefImpl(getter, setter, isSSR);
1600
+ if (!!(process.env.NODE_ENV !== "production") && debugOptions && !isSSR) {
1601
+ cRef.onTrack = debugOptions.onTrack;
1602
+ cRef.onTrigger = debugOptions.onTrigger;
1603
+ }
1604
+ return cRef;
1605
+ }
1218
1606
 
1219
1607
  const TrackOpTypes = {
1220
1608
  "GET": "get",
@@ -1235,4 +1623,4 @@ const ReactiveFlags = {
1235
1623
  "RAW": "__v_raw"
1236
1624
  };
1237
1625
 
1238
- 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 };
1626
+ 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 };