@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,5 +1,5 @@
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
  **/
@@ -95,156 +95,296 @@ class EffectScope {
95
95
  function effectScope(detached) {
96
96
  return new EffectScope(detached);
97
97
  }
98
- function recordEffectScope(effect, scope = activeEffectScope) {
99
- if (scope && scope.active) {
100
- scope.effects.push(effect);
101
- }
102
- }
103
98
  function getCurrentScope() {
104
99
  return activeEffectScope;
105
100
  }
106
- function onScopeDispose(fn) {
101
+ function onScopeDispose(fn, failSilently = false) {
107
102
  if (activeEffectScope) {
108
103
  activeEffectScope.cleanups.push(fn);
109
- } else {
104
+ } else if (!failSilently) {
110
105
  warn(
111
106
  `onScopeDispose() is called when there is no active effect scope to be associated with.`
112
107
  );
113
108
  }
114
109
  }
115
110
 
116
- let activeEffect;
111
+ let activeSub;
112
+ const EffectFlags = {
113
+ "ACTIVE": 1,
114
+ "1": "ACTIVE",
115
+ "RUNNING": 2,
116
+ "2": "RUNNING",
117
+ "TRACKING": 4,
118
+ "4": "TRACKING",
119
+ "NOTIFIED": 8,
120
+ "8": "NOTIFIED",
121
+ "DIRTY": 16,
122
+ "16": "DIRTY",
123
+ "ALLOW_RECURSE": 32,
124
+ "32": "ALLOW_RECURSE",
125
+ "NO_BATCH": 64,
126
+ "64": "NO_BATCH"
127
+ };
117
128
  class ReactiveEffect {
118
- constructor(fn, trigger, scheduler, scope) {
129
+ constructor(fn) {
119
130
  this.fn = fn;
120
- this.trigger = trigger;
121
- this.scheduler = scheduler;
122
- this.active = true;
123
- this.deps = [];
124
131
  /**
125
132
  * @internal
126
133
  */
127
- this._dirtyLevel = 4;
134
+ this.deps = void 0;
128
135
  /**
129
136
  * @internal
130
137
  */
131
- this._trackId = 0;
138
+ this.depsTail = void 0;
132
139
  /**
133
140
  * @internal
134
141
  */
135
- this._runnings = 0;
142
+ this.flags = 1 | 4;
136
143
  /**
137
144
  * @internal
138
145
  */
139
- this._shouldSchedule = false;
146
+ this.nextEffect = void 0;
140
147
  /**
141
148
  * @internal
142
149
  */
143
- this._depsLength = 0;
144
- recordEffectScope(this, scope);
145
- }
146
- get dirty() {
147
- if (this._dirtyLevel === 2 || this._dirtyLevel === 3) {
148
- this._dirtyLevel = 1;
149
- pauseTracking();
150
- for (let i = 0; i < this._depsLength; i++) {
151
- const dep = this.deps[i];
152
- if (dep.computed) {
153
- triggerComputed(dep.computed);
154
- if (this._dirtyLevel >= 4) {
155
- break;
156
- }
157
- }
158
- }
159
- if (this._dirtyLevel === 1) {
160
- this._dirtyLevel = 0;
161
- }
162
- resetTracking();
150
+ this.cleanup = void 0;
151
+ this.scheduler = void 0;
152
+ if (activeEffectScope && activeEffectScope.active) {
153
+ activeEffectScope.effects.push(this);
163
154
  }
164
- return this._dirtyLevel >= 4;
165
155
  }
166
- set dirty(v) {
167
- this._dirtyLevel = v ? 4 : 0;
156
+ /**
157
+ * @internal
158
+ */
159
+ notify() {
160
+ if (this.flags & 2 && !(this.flags & 32)) {
161
+ return;
162
+ }
163
+ if (this.flags & 64) {
164
+ return this.trigger();
165
+ }
166
+ if (!(this.flags & 8)) {
167
+ this.flags |= 8;
168
+ this.nextEffect = batchedEffect;
169
+ batchedEffect = this;
170
+ }
168
171
  }
169
172
  run() {
170
- this._dirtyLevel = 0;
171
- if (!this.active) {
173
+ if (!(this.flags & 1)) {
172
174
  return this.fn();
173
175
  }
174
- let lastShouldTrack = shouldTrack;
175
- let lastEffect = activeEffect;
176
+ this.flags |= 2;
177
+ cleanupEffect(this);
178
+ prepareDeps(this);
179
+ const prevEffect = activeSub;
180
+ const prevShouldTrack = shouldTrack;
181
+ activeSub = this;
182
+ shouldTrack = true;
176
183
  try {
177
- shouldTrack = true;
178
- activeEffect = this;
179
- this._runnings++;
180
- preCleanupEffect(this);
181
184
  return this.fn();
182
185
  } finally {
183
- postCleanupEffect(this);
184
- this._runnings--;
185
- activeEffect = lastEffect;
186
- shouldTrack = lastShouldTrack;
186
+ if (activeSub !== this) {
187
+ warn(
188
+ "Active effect was not restored correctly - this is likely a Vue internal bug."
189
+ );
190
+ }
191
+ cleanupDeps(this);
192
+ activeSub = prevEffect;
193
+ shouldTrack = prevShouldTrack;
194
+ this.flags &= ~2;
187
195
  }
188
196
  }
189
197
  stop() {
190
- if (this.active) {
191
- preCleanupEffect(this);
192
- postCleanupEffect(this);
198
+ if (this.flags & 1) {
199
+ for (let link = this.deps; link; link = link.nextDep) {
200
+ removeSub(link);
201
+ }
202
+ this.deps = this.depsTail = void 0;
203
+ cleanupEffect(this);
193
204
  this.onStop && this.onStop();
194
- this.active = false;
205
+ this.flags &= ~1;
206
+ }
207
+ }
208
+ trigger() {
209
+ if (this.scheduler) {
210
+ this.scheduler();
211
+ } else {
212
+ this.runIfDirty();
213
+ }
214
+ }
215
+ /**
216
+ * @internal
217
+ */
218
+ runIfDirty() {
219
+ if (isDirty(this)) {
220
+ this.run();
195
221
  }
196
222
  }
223
+ get dirty() {
224
+ return isDirty(this);
225
+ }
197
226
  }
198
- function triggerComputed(computed) {
199
- return computed.value;
227
+ let batchDepth = 0;
228
+ let batchedEffect;
229
+ function startBatch() {
230
+ batchDepth++;
200
231
  }
201
- function preCleanupEffect(effect2) {
202
- effect2._trackId++;
203
- effect2._depsLength = 0;
232
+ function endBatch() {
233
+ if (batchDepth > 1) {
234
+ batchDepth--;
235
+ return;
236
+ }
237
+ let error;
238
+ while (batchedEffect) {
239
+ let e = batchedEffect;
240
+ batchedEffect = void 0;
241
+ while (e) {
242
+ const next = e.nextEffect;
243
+ e.nextEffect = void 0;
244
+ e.flags &= ~8;
245
+ if (e.flags & 1) {
246
+ try {
247
+ e.trigger();
248
+ } catch (err) {
249
+ if (!error)
250
+ error = err;
251
+ }
252
+ }
253
+ e = next;
254
+ }
255
+ }
256
+ batchDepth--;
257
+ if (error)
258
+ throw error;
259
+ }
260
+ function prepareDeps(sub) {
261
+ for (let link = sub.deps; link; link = link.nextDep) {
262
+ link.version = -1;
263
+ link.prevActiveLink = link.dep.activeLink;
264
+ link.dep.activeLink = link;
265
+ }
266
+ }
267
+ function cleanupDeps(sub) {
268
+ let head;
269
+ let tail = sub.depsTail;
270
+ for (let link = tail; link; link = link.prevDep) {
271
+ if (link.version === -1) {
272
+ if (link === tail)
273
+ tail = link.prevDep;
274
+ removeSub(link);
275
+ removeDep(link);
276
+ } else {
277
+ head = link;
278
+ }
279
+ link.dep.activeLink = link.prevActiveLink;
280
+ link.prevActiveLink = void 0;
281
+ }
282
+ sub.deps = head;
283
+ sub.depsTail = tail;
204
284
  }
205
- function postCleanupEffect(effect2) {
206
- if (effect2.deps.length > effect2._depsLength) {
207
- for (let i = effect2._depsLength; i < effect2.deps.length; i++) {
208
- cleanupDepEffect(effect2.deps[i], effect2);
285
+ function isDirty(sub) {
286
+ for (let link = sub.deps; link; link = link.nextDep) {
287
+ if (link.dep.version !== link.version || link.dep.computed && refreshComputed(link.dep.computed) === false || link.dep.version !== link.version) {
288
+ return true;
209
289
  }
210
- effect2.deps.length = effect2._depsLength;
211
290
  }
291
+ if (sub._dirty) {
292
+ return true;
293
+ }
294
+ return false;
212
295
  }
213
- function cleanupDepEffect(dep, effect2) {
214
- const trackId = dep.get(effect2);
215
- if (trackId !== void 0 && effect2._trackId !== trackId) {
216
- dep.delete(effect2);
217
- if (dep.size === 0) {
218
- dep.cleanup();
296
+ function refreshComputed(computed) {
297
+ if (computed.flags & 2) {
298
+ return false;
299
+ }
300
+ if (computed.flags & 4 && !(computed.flags & 16)) {
301
+ return;
302
+ }
303
+ computed.flags &= ~16;
304
+ if (computed.globalVersion === globalVersion) {
305
+ return;
306
+ }
307
+ computed.globalVersion = globalVersion;
308
+ const dep = computed.dep;
309
+ computed.flags |= 2;
310
+ if (dep.version > 0 && !computed.isSSR && !isDirty(computed)) {
311
+ computed.flags &= ~2;
312
+ return;
313
+ }
314
+ const prevSub = activeSub;
315
+ const prevShouldTrack = shouldTrack;
316
+ activeSub = computed;
317
+ shouldTrack = true;
318
+ try {
319
+ prepareDeps(computed);
320
+ const value = computed.fn();
321
+ if (dep.version === 0 || shared.hasChanged(value, computed._value)) {
322
+ computed._value = value;
323
+ dep.version++;
324
+ }
325
+ } catch (err) {
326
+ dep.version++;
327
+ throw err;
328
+ } finally {
329
+ activeSub = prevSub;
330
+ shouldTrack = prevShouldTrack;
331
+ cleanupDeps(computed);
332
+ computed.flags &= ~2;
333
+ }
334
+ }
335
+ function removeSub(link) {
336
+ const { dep, prevSub, nextSub } = link;
337
+ if (prevSub) {
338
+ prevSub.nextSub = nextSub;
339
+ link.prevSub = void 0;
340
+ }
341
+ if (nextSub) {
342
+ nextSub.prevSub = prevSub;
343
+ link.nextSub = void 0;
344
+ }
345
+ if (dep.subs === link) {
346
+ dep.subs = prevSub;
347
+ }
348
+ if (!dep.subs && dep.computed) {
349
+ dep.computed.flags &= ~4;
350
+ for (let l = dep.computed.deps; l; l = l.nextDep) {
351
+ removeSub(l);
219
352
  }
220
353
  }
221
354
  }
355
+ function removeDep(link) {
356
+ const { prevDep, nextDep } = link;
357
+ if (prevDep) {
358
+ prevDep.nextDep = nextDep;
359
+ link.prevDep = void 0;
360
+ }
361
+ if (nextDep) {
362
+ nextDep.prevDep = prevDep;
363
+ link.nextDep = void 0;
364
+ }
365
+ }
222
366
  function effect(fn, options) {
223
367
  if (fn.effect instanceof ReactiveEffect) {
224
368
  fn = fn.effect.fn;
225
369
  }
226
- const _effect = new ReactiveEffect(fn, shared.NOOP, () => {
227
- if (_effect.dirty) {
228
- _effect.run();
229
- }
230
- });
370
+ const e = new ReactiveEffect(fn);
231
371
  if (options) {
232
- shared.extend(_effect, options);
233
- if (options.scope)
234
- recordEffectScope(_effect, options.scope);
372
+ shared.extend(e, options);
235
373
  }
236
- if (!options || !options.lazy) {
237
- _effect.run();
374
+ try {
375
+ e.run();
376
+ } catch (err) {
377
+ e.stop();
378
+ throw err;
238
379
  }
239
- const runner = _effect.run.bind(_effect);
240
- runner.effect = _effect;
380
+ const runner = e.run.bind(e);
381
+ runner.effect = e;
241
382
  return runner;
242
383
  }
243
384
  function stop(runner) {
244
385
  runner.effect.stop();
245
386
  }
246
387
  let shouldTrack = true;
247
- let pauseScheduleStack = 0;
248
388
  const trackStack = [];
249
389
  function pauseTracking() {
250
390
  trackStack.push(shouldTrack);
@@ -258,192 +398,423 @@ function resetTracking() {
258
398
  const last = trackStack.pop();
259
399
  shouldTrack = last === void 0 ? true : last;
260
400
  }
261
- function pauseScheduling() {
262
- pauseScheduleStack++;
263
- }
264
- function resetScheduling() {
265
- pauseScheduleStack--;
266
- while (!pauseScheduleStack && queueEffectSchedulers.length) {
267
- queueEffectSchedulers.shift()();
401
+ function onEffectCleanup(fn, failSilently = false) {
402
+ if (activeSub instanceof ReactiveEffect) {
403
+ activeSub.cleanup = fn;
404
+ } else if (!failSilently) {
405
+ warn(
406
+ `onEffectCleanup() was called when there was no active effect to associate with.`
407
+ );
268
408
  }
269
409
  }
270
- function trackEffect(effect2, dep, debuggerEventExtraInfo) {
271
- var _a;
272
- if (dep.get(effect2) !== effect2._trackId) {
273
- dep.set(effect2, effect2._trackId);
274
- const oldDep = effect2.deps[effect2._depsLength];
275
- if (oldDep !== dep) {
276
- if (oldDep) {
277
- cleanupDepEffect(oldDep, effect2);
278
- }
279
- effect2.deps[effect2._depsLength++] = dep;
280
- } else {
281
- effect2._depsLength++;
410
+ function cleanupEffect(e) {
411
+ const { cleanup } = e;
412
+ e.cleanup = void 0;
413
+ if (cleanup) {
414
+ const prevSub = activeSub;
415
+ activeSub = void 0;
416
+ try {
417
+ cleanup();
418
+ } finally {
419
+ activeSub = prevSub;
282
420
  }
421
+ }
422
+ }
423
+
424
+ let globalVersion = 0;
425
+ class Dep {
426
+ constructor(computed) {
427
+ this.computed = computed;
428
+ this.version = 0;
429
+ /**
430
+ * Link between this dep and the current active effect
431
+ */
432
+ this.activeLink = void 0;
433
+ /**
434
+ * Doubly linked list representing the subscribing effects (tail)
435
+ */
436
+ this.subs = void 0;
283
437
  {
284
- (_a = effect2.onTrack) == null ? void 0 : _a.call(effect2, shared.extend({ effect: effect2 }, debuggerEventExtraInfo));
438
+ this.subsHead = void 0;
285
439
  }
286
440
  }
287
- }
288
- const queueEffectSchedulers = [];
289
- function triggerEffects(dep, dirtyLevel, debuggerEventExtraInfo) {
290
- var _a;
291
- pauseScheduling();
292
- for (const effect2 of dep.keys()) {
293
- let tracking;
294
- if (effect2._dirtyLevel < dirtyLevel && (tracking != null ? tracking : tracking = dep.get(effect2) === effect2._trackId)) {
295
- effect2._shouldSchedule || (effect2._shouldSchedule = effect2._dirtyLevel === 0);
296
- effect2._dirtyLevel = dirtyLevel;
441
+ track(debugInfo) {
442
+ if (!activeSub || !shouldTrack) {
443
+ return;
297
444
  }
298
- if (effect2._shouldSchedule && (tracking != null ? tracking : tracking = dep.get(effect2) === effect2._trackId)) {
299
- {
300
- (_a = effect2.onTrigger) == null ? void 0 : _a.call(effect2, shared.extend({ effect: effect2 }, debuggerEventExtraInfo));
445
+ let link = this.activeLink;
446
+ if (link === void 0 || link.sub !== activeSub) {
447
+ link = this.activeLink = {
448
+ dep: this,
449
+ sub: activeSub,
450
+ version: this.version,
451
+ nextDep: void 0,
452
+ prevDep: void 0,
453
+ nextSub: void 0,
454
+ prevSub: void 0,
455
+ prevActiveLink: void 0
456
+ };
457
+ if (!activeSub.deps) {
458
+ activeSub.deps = activeSub.depsTail = link;
459
+ } else {
460
+ link.prevDep = activeSub.depsTail;
461
+ activeSub.depsTail.nextDep = link;
462
+ activeSub.depsTail = link;
463
+ }
464
+ if (activeSub.flags & 4) {
465
+ addSub(link);
466
+ }
467
+ } else if (link.version === -1) {
468
+ link.version = this.version;
469
+ if (link.nextDep) {
470
+ const next = link.nextDep;
471
+ next.prevDep = link.prevDep;
472
+ if (link.prevDep) {
473
+ link.prevDep.nextDep = next;
474
+ }
475
+ link.prevDep = activeSub.depsTail;
476
+ link.nextDep = void 0;
477
+ activeSub.depsTail.nextDep = link;
478
+ activeSub.depsTail = link;
479
+ if (activeSub.deps === link) {
480
+ activeSub.deps = next;
481
+ }
301
482
  }
302
- effect2.trigger();
303
- if ((!effect2._runnings || effect2.allowRecurse) && effect2._dirtyLevel !== 2) {
304
- effect2._shouldSchedule = false;
305
- if (effect2.scheduler) {
306
- queueEffectSchedulers.push(effect2.scheduler);
483
+ }
484
+ if (activeSub.onTrack) {
485
+ activeSub.onTrack(
486
+ shared.extend(
487
+ {
488
+ effect: activeSub
489
+ },
490
+ debugInfo
491
+ )
492
+ );
493
+ }
494
+ return link;
495
+ }
496
+ trigger(debugInfo) {
497
+ this.version++;
498
+ globalVersion++;
499
+ this.notify(debugInfo);
500
+ }
501
+ notify(debugInfo) {
502
+ startBatch();
503
+ try {
504
+ if (true) {
505
+ for (let head = this.subsHead; head; head = head.nextSub) {
506
+ if (head.sub.onTrigger && !(head.sub.flags & 8)) {
507
+ head.sub.onTrigger(
508
+ shared.extend(
509
+ {
510
+ effect: head.sub
511
+ },
512
+ debugInfo
513
+ )
514
+ );
515
+ }
307
516
  }
308
517
  }
518
+ for (let link = this.subs; link; link = link.prevSub) {
519
+ link.sub.notify();
520
+ }
521
+ } finally {
522
+ endBatch();
309
523
  }
310
524
  }
311
- resetScheduling();
312
525
  }
313
-
314
- const createDep = (cleanup, computed) => {
315
- const dep = /* @__PURE__ */ new Map();
316
- dep.cleanup = cleanup;
317
- dep.computed = computed;
318
- return dep;
319
- };
320
-
526
+ function addSub(link) {
527
+ const computed = link.dep.computed;
528
+ if (computed && !link.dep.subs) {
529
+ computed.flags |= 4 | 16;
530
+ for (let l = computed.deps; l; l = l.nextDep) {
531
+ addSub(l);
532
+ }
533
+ }
534
+ const currentTail = link.dep.subs;
535
+ if (currentTail !== link) {
536
+ link.prevSub = currentTail;
537
+ if (currentTail)
538
+ currentTail.nextSub = link;
539
+ }
540
+ if (link.dep.subsHead === void 0) {
541
+ link.dep.subsHead = link;
542
+ }
543
+ link.dep.subs = link;
544
+ }
321
545
  const targetMap = /* @__PURE__ */ new WeakMap();
322
- const ITERATE_KEY = Symbol("iterate" );
323
- const MAP_KEY_ITERATE_KEY = Symbol("Map key iterate" );
546
+ const ITERATE_KEY = Symbol("Object iterate" );
547
+ const MAP_KEY_ITERATE_KEY = Symbol("Map keys iterate" );
548
+ const ARRAY_ITERATE_KEY = Symbol("Array iterate" );
324
549
  function track(target, type, key) {
325
- if (shouldTrack && activeEffect) {
550
+ if (shouldTrack && activeSub) {
326
551
  let depsMap = targetMap.get(target);
327
552
  if (!depsMap) {
328
553
  targetMap.set(target, depsMap = /* @__PURE__ */ new Map());
329
554
  }
330
555
  let dep = depsMap.get(key);
331
556
  if (!dep) {
332
- depsMap.set(key, dep = createDep(() => depsMap.delete(key)));
557
+ depsMap.set(key, dep = new Dep());
333
558
  }
334
- trackEffect(
335
- activeEffect,
336
- dep,
337
- {
559
+ {
560
+ dep.track({
338
561
  target,
339
562
  type,
340
563
  key
341
- }
342
- );
564
+ });
565
+ }
343
566
  }
344
567
  }
345
568
  function trigger(target, type, key, newValue, oldValue, oldTarget) {
346
569
  const depsMap = targetMap.get(target);
347
570
  if (!depsMap) {
571
+ globalVersion++;
348
572
  return;
349
573
  }
350
574
  let deps = [];
351
575
  if (type === "clear") {
352
576
  deps = [...depsMap.values()];
353
- } else if (key === "length" && shared.isArray(target)) {
354
- const newLength = Number(newValue);
355
- depsMap.forEach((dep, key2) => {
356
- if (key2 === "length" || !shared.isSymbol(key2) && key2 >= newLength) {
357
- deps.push(dep);
358
- }
359
- });
360
577
  } else {
361
- if (key !== void 0) {
362
- deps.push(depsMap.get(key));
363
- }
364
- switch (type) {
365
- case "add":
366
- if (!shared.isArray(target)) {
367
- deps.push(depsMap.get(ITERATE_KEY));
368
- if (shared.isMap(target)) {
369
- deps.push(depsMap.get(MAP_KEY_ITERATE_KEY));
370
- }
371
- } else if (shared.isIntegerKey(key)) {
372
- deps.push(depsMap.get("length"));
578
+ const targetIsArray = shared.isArray(target);
579
+ const isArrayIndex = targetIsArray && shared.isIntegerKey(key);
580
+ if (targetIsArray && key === "length") {
581
+ const newLength = Number(newValue);
582
+ depsMap.forEach((dep, key2) => {
583
+ if (key2 === "length" || key2 === ARRAY_ITERATE_KEY || !shared.isSymbol(key2) && key2 >= newLength) {
584
+ deps.push(dep);
373
585
  }
374
- break;
375
- case "delete":
376
- if (!shared.isArray(target)) {
377
- deps.push(depsMap.get(ITERATE_KEY));
586
+ });
587
+ } else {
588
+ const push = (dep) => dep && deps.push(dep);
589
+ if (key !== void 0) {
590
+ push(depsMap.get(key));
591
+ }
592
+ if (isArrayIndex) {
593
+ push(depsMap.get(ARRAY_ITERATE_KEY));
594
+ }
595
+ switch (type) {
596
+ case "add":
597
+ if (!targetIsArray) {
598
+ push(depsMap.get(ITERATE_KEY));
599
+ if (shared.isMap(target)) {
600
+ push(depsMap.get(MAP_KEY_ITERATE_KEY));
601
+ }
602
+ } else if (isArrayIndex) {
603
+ push(depsMap.get("length"));
604
+ }
605
+ break;
606
+ case "delete":
607
+ if (!targetIsArray) {
608
+ push(depsMap.get(ITERATE_KEY));
609
+ if (shared.isMap(target)) {
610
+ push(depsMap.get(MAP_KEY_ITERATE_KEY));
611
+ }
612
+ }
613
+ break;
614
+ case "set":
378
615
  if (shared.isMap(target)) {
379
- deps.push(depsMap.get(MAP_KEY_ITERATE_KEY));
616
+ push(depsMap.get(ITERATE_KEY));
380
617
  }
381
- }
382
- break;
383
- case "set":
384
- if (shared.isMap(target)) {
385
- deps.push(depsMap.get(ITERATE_KEY));
386
- }
387
- break;
618
+ break;
619
+ }
388
620
  }
389
621
  }
390
- pauseScheduling();
622
+ startBatch();
391
623
  for (const dep of deps) {
392
- if (dep) {
393
- triggerEffects(
394
- dep,
395
- 4,
396
- {
397
- target,
398
- type,
399
- key,
400
- newValue,
401
- oldValue,
402
- oldTarget
403
- }
404
- );
624
+ {
625
+ dep.trigger({
626
+ target,
627
+ type,
628
+ key,
629
+ newValue,
630
+ oldValue,
631
+ oldTarget
632
+ });
405
633
  }
406
634
  }
407
- resetScheduling();
635
+ endBatch();
408
636
  }
409
637
  function getDepFromReactive(object, key) {
410
- const depsMap = targetMap.get(object);
411
- 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;
412
812
  }
413
813
 
414
814
  const isNonTrackableKeys = /* @__PURE__ */ shared.makeMap(`__proto__,__v_isRef,__isVue`);
415
815
  const builtInSymbols = new Set(
416
816
  /* @__PURE__ */ Object.getOwnPropertyNames(Symbol).filter((key) => key !== "arguments" && key !== "caller").map((key) => Symbol[key]).filter(shared.isSymbol)
417
817
  );
418
- const arrayInstrumentations = /* @__PURE__ */ createArrayInstrumentations();
419
- function createArrayInstrumentations() {
420
- const instrumentations = {};
421
- ["includes", "indexOf", "lastIndexOf"].forEach((key) => {
422
- instrumentations[key] = function(...args) {
423
- const arr = toRaw(this);
424
- for (let i = 0, l = this.length; i < l; i++) {
425
- track(arr, "get", i + "");
426
- }
427
- const res = arr[key](...args);
428
- if (res === -1 || res === false) {
429
- return arr[key](...args.map(toRaw));
430
- } else {
431
- return res;
432
- }
433
- };
434
- });
435
- ["push", "pop", "shift", "unshift", "splice"].forEach((key) => {
436
- instrumentations[key] = function(...args) {
437
- pauseTracking();
438
- pauseScheduling();
439
- const res = toRaw(this)[key].apply(this, args);
440
- resetScheduling();
441
- resetTracking();
442
- return res;
443
- };
444
- });
445
- return instrumentations;
446
- }
447
818
  function hasOwnProperty(key) {
448
819
  if (!shared.isSymbol(key))
449
820
  key = String(key);
@@ -474,14 +845,22 @@ class BaseReactiveHandler {
474
845
  }
475
846
  const targetIsArray = shared.isArray(target);
476
847
  if (!isReadonly2) {
477
- if (targetIsArray && shared.hasOwn(arrayInstrumentations, key)) {
478
- return Reflect.get(arrayInstrumentations, key, receiver);
848
+ let fn;
849
+ if (targetIsArray && (fn = arrayInstrumentations[key])) {
850
+ return fn;
479
851
  }
480
852
  if (key === "hasOwnProperty") {
481
853
  return hasOwnProperty;
482
854
  }
483
855
  }
484
- 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
+ );
485
864
  if (shared.isSymbol(key) ? builtInSymbols.has(key) : isNonTrackableKeys(key)) {
486
865
  return res;
487
866
  }
@@ -980,110 +1359,8 @@ function markRaw(value) {
980
1359
  const toReactive = (value) => shared.isObject(value) ? reactive(value) : value;
981
1360
  const toReadonly = (value) => shared.isObject(value) ? readonly(value) : value;
982
1361
 
983
- 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`;
984
- class ComputedRefImpl {
985
- constructor(getter, _setter, isReadonly, isSSR) {
986
- this.getter = getter;
987
- this._setter = _setter;
988
- this.dep = void 0;
989
- this.__v_isRef = true;
990
- this["__v_isReadonly"] = false;
991
- this.effect = new ReactiveEffect(
992
- () => getter(this._value),
993
- () => triggerRefValue(
994
- this,
995
- this.effect._dirtyLevel === 2 ? 2 : 3
996
- )
997
- );
998
- this.effect.computed = this;
999
- this.effect.active = this._cacheable = !isSSR;
1000
- this["__v_isReadonly"] = isReadonly;
1001
- }
1002
- get value() {
1003
- const self = toRaw(this);
1004
- if ((!self._cacheable || self.effect.dirty) && shared.hasChanged(self._value, self._value = self.effect.run())) {
1005
- triggerRefValue(self, 4);
1006
- }
1007
- trackRefValue(self);
1008
- if (self.effect._dirtyLevel >= 2) {
1009
- if (this._warnRecursive) {
1010
- warn(COMPUTED_SIDE_EFFECT_WARN, `
1011
-
1012
- getter: `, this.getter);
1013
- }
1014
- triggerRefValue(self, 2);
1015
- }
1016
- return self._value;
1017
- }
1018
- set value(newValue) {
1019
- this._setter(newValue);
1020
- }
1021
- // #region polyfill _dirty for backward compatibility third party code for Vue <= 3.3.x
1022
- get _dirty() {
1023
- return this.effect.dirty;
1024
- }
1025
- set _dirty(v) {
1026
- this.effect.dirty = v;
1027
- }
1028
- // #endregion
1029
- }
1030
- function computed(getterOrOptions, debugOptions, isSSR = false) {
1031
- let getter;
1032
- let setter;
1033
- const onlyGetter = shared.isFunction(getterOrOptions);
1034
- if (onlyGetter) {
1035
- getter = getterOrOptions;
1036
- setter = () => {
1037
- warn("Write operation failed: computed value is readonly");
1038
- } ;
1039
- } else {
1040
- getter = getterOrOptions.get;
1041
- setter = getterOrOptions.set;
1042
- }
1043
- const cRef = new ComputedRefImpl(getter, setter, onlyGetter || !setter, isSSR);
1044
- if (debugOptions && !isSSR) {
1045
- cRef.effect.onTrack = debugOptions.onTrack;
1046
- cRef.effect.onTrigger = debugOptions.onTrigger;
1047
- }
1048
- return cRef;
1049
- }
1050
-
1051
- function trackRefValue(ref2) {
1052
- var _a;
1053
- if (shouldTrack && activeEffect) {
1054
- ref2 = toRaw(ref2);
1055
- trackEffect(
1056
- activeEffect,
1057
- (_a = ref2.dep) != null ? _a : ref2.dep = createDep(
1058
- () => ref2.dep = void 0,
1059
- ref2 instanceof ComputedRefImpl ? ref2 : void 0
1060
- ),
1061
- {
1062
- target: ref2,
1063
- type: "get",
1064
- key: "value"
1065
- }
1066
- );
1067
- }
1068
- }
1069
- function triggerRefValue(ref2, dirtyLevel = 4, newVal) {
1070
- ref2 = toRaw(ref2);
1071
- const dep = ref2.dep;
1072
- if (dep) {
1073
- triggerEffects(
1074
- dep,
1075
- dirtyLevel,
1076
- {
1077
- target: ref2,
1078
- type: "set",
1079
- key: "value",
1080
- newValue: newVal
1081
- }
1082
- );
1083
- }
1084
- }
1085
1362
  function isRef(r) {
1086
- return !!(r && r.__v_isRef === true);
1363
+ return r ? r.__v_isRef === true : false;
1087
1364
  }
1088
1365
  function ref(value) {
1089
1366
  return createRef(value, false);
@@ -1100,27 +1377,49 @@ function createRef(rawValue, shallow) {
1100
1377
  class RefImpl {
1101
1378
  constructor(value, __v_isShallow) {
1102
1379
  this.__v_isShallow = __v_isShallow;
1103
- this.dep = void 0;
1380
+ this.dep = new Dep();
1104
1381
  this.__v_isRef = true;
1105
1382
  this._rawValue = __v_isShallow ? value : toRaw(value);
1106
1383
  this._value = __v_isShallow ? value : toReactive(value);
1107
1384
  }
1108
1385
  get value() {
1109
- trackRefValue(this);
1386
+ {
1387
+ this.dep.track({
1388
+ target: this,
1389
+ type: "get",
1390
+ key: "value"
1391
+ });
1392
+ }
1110
1393
  return this._value;
1111
1394
  }
1112
- set value(newVal) {
1113
- const useDirectValue = this.__v_isShallow || isShallow(newVal) || isReadonly(newVal);
1114
- newVal = useDirectValue ? newVal : toRaw(newVal);
1115
- if (shared.hasChanged(newVal, this._rawValue)) {
1116
- this._rawValue = newVal;
1117
- this._value = useDirectValue ? newVal : toReactive(newVal);
1118
- triggerRefValue(this, 4, newVal);
1395
+ set value(newValue) {
1396
+ const oldValue = this._rawValue;
1397
+ const useDirectValue = this.__v_isShallow || isShallow(newValue) || isReadonly(newValue);
1398
+ newValue = useDirectValue ? newValue : toRaw(newValue);
1399
+ if (shared.hasChanged(newValue, oldValue)) {
1400
+ this._rawValue = newValue;
1401
+ this._value = useDirectValue ? newValue : toReactive(newValue);
1402
+ {
1403
+ this.dep.trigger({
1404
+ target: this,
1405
+ type: "set",
1406
+ key: "value",
1407
+ newValue,
1408
+ oldValue
1409
+ });
1410
+ }
1119
1411
  }
1120
1412
  }
1121
1413
  }
1122
1414
  function triggerRef(ref2) {
1123
- triggerRefValue(ref2, 4, ref2.value );
1415
+ {
1416
+ ref2.dep.trigger({
1417
+ target: ref2,
1418
+ type: "set",
1419
+ key: "value",
1420
+ newValue: ref2._value
1421
+ });
1422
+ }
1124
1423
  }
1125
1424
  function unref(ref2) {
1126
1425
  return isRef(ref2) ? ref2.value : ref2;
@@ -1145,12 +1444,9 @@ function proxyRefs(objectWithRefs) {
1145
1444
  }
1146
1445
  class CustomRefImpl {
1147
1446
  constructor(factory) {
1148
- this.dep = void 0;
1149
1447
  this.__v_isRef = true;
1150
- const { get, set } = factory(
1151
- () => trackRefValue(this),
1152
- () => triggerRefValue(this)
1153
- );
1448
+ const dep = this.dep = new Dep();
1449
+ const { get, set } = factory(dep.track.bind(dep), dep.trigger.bind(dep));
1154
1450
  this._get = get;
1155
1451
  this._set = set;
1156
1452
  }
@@ -1218,7 +1514,89 @@ function propertyToRef(source, key, defaultValue) {
1218
1514
  return isRef(val) ? val : new ObjectRefImpl(source, key, defaultValue);
1219
1515
  }
1220
1516
 
1221
- const deferredComputed = computed;
1517
+ class ComputedRefImpl {
1518
+ constructor(fn, setter, isSSR) {
1519
+ this.fn = fn;
1520
+ this.setter = setter;
1521
+ /**
1522
+ * @internal
1523
+ */
1524
+ this._value = void 0;
1525
+ /**
1526
+ * @internal
1527
+ */
1528
+ this.dep = new Dep(this);
1529
+ /**
1530
+ * @internal
1531
+ */
1532
+ this.__v_isRef = true;
1533
+ // A computed is also a subscriber that tracks other deps
1534
+ /**
1535
+ * @internal
1536
+ */
1537
+ this.deps = void 0;
1538
+ /**
1539
+ * @internal
1540
+ */
1541
+ this.depsTail = void 0;
1542
+ /**
1543
+ * @internal
1544
+ */
1545
+ this.flags = 16;
1546
+ /**
1547
+ * @internal
1548
+ */
1549
+ this.globalVersion = globalVersion - 1;
1550
+ // for backwards compat
1551
+ this.effect = this;
1552
+ this.__v_isReadonly = !setter;
1553
+ this.isSSR = isSSR;
1554
+ }
1555
+ /**
1556
+ * @internal
1557
+ */
1558
+ notify() {
1559
+ if (activeSub !== this) {
1560
+ this.flags |= 16;
1561
+ this.dep.notify();
1562
+ }
1563
+ }
1564
+ get value() {
1565
+ const link = this.dep.track({
1566
+ target: this,
1567
+ type: "get",
1568
+ key: "value"
1569
+ }) ;
1570
+ refreshComputed(this);
1571
+ if (link) {
1572
+ link.version = this.dep.version;
1573
+ }
1574
+ return this._value;
1575
+ }
1576
+ set value(newValue) {
1577
+ if (this.setter) {
1578
+ this.setter(newValue);
1579
+ } else {
1580
+ warn("Write operation failed: computed value is readonly");
1581
+ }
1582
+ }
1583
+ }
1584
+ function computed(getterOrOptions, debugOptions, isSSR = false) {
1585
+ let getter;
1586
+ let setter;
1587
+ if (shared.isFunction(getterOrOptions)) {
1588
+ getter = getterOrOptions;
1589
+ } else {
1590
+ getter = getterOrOptions.get;
1591
+ setter = getterOrOptions.set;
1592
+ }
1593
+ const cRef = new ComputedRefImpl(getter, setter, isSSR);
1594
+ if (debugOptions && !isSSR) {
1595
+ cRef.onTrack = debugOptions.onTrack;
1596
+ cRef.onTrigger = debugOptions.onTrigger;
1597
+ }
1598
+ return cRef;
1599
+ }
1222
1600
 
1223
1601
  const TrackOpTypes = {
1224
1602
  "GET": "get",
@@ -1239,15 +1617,17 @@ const ReactiveFlags = {
1239
1617
  "RAW": "__v_raw"
1240
1618
  };
1241
1619
 
1620
+ exports.ARRAY_ITERATE_KEY = ARRAY_ITERATE_KEY;
1621
+ exports.EffectFlags = EffectFlags;
1242
1622
  exports.EffectScope = EffectScope;
1243
1623
  exports.ITERATE_KEY = ITERATE_KEY;
1624
+ exports.MAP_KEY_ITERATE_KEY = MAP_KEY_ITERATE_KEY;
1244
1625
  exports.ReactiveEffect = ReactiveEffect;
1245
1626
  exports.ReactiveFlags = ReactiveFlags;
1246
1627
  exports.TrackOpTypes = TrackOpTypes;
1247
1628
  exports.TriggerOpTypes = TriggerOpTypes;
1248
1629
  exports.computed = computed;
1249
1630
  exports.customRef = customRef;
1250
- exports.deferredComputed = deferredComputed;
1251
1631
  exports.effect = effect;
1252
1632
  exports.effectScope = effectScope;
1253
1633
  exports.enableTracking = enableTracking;
@@ -1258,20 +1638,23 @@ exports.isReadonly = isReadonly;
1258
1638
  exports.isRef = isRef;
1259
1639
  exports.isShallow = isShallow;
1260
1640
  exports.markRaw = markRaw;
1641
+ exports.onEffectCleanup = onEffectCleanup;
1261
1642
  exports.onScopeDispose = onScopeDispose;
1262
- exports.pauseScheduling = pauseScheduling;
1263
1643
  exports.pauseTracking = pauseTracking;
1264
1644
  exports.proxyRefs = proxyRefs;
1265
1645
  exports.reactive = reactive;
1646
+ exports.reactiveReadArray = reactiveReadArray;
1266
1647
  exports.readonly = readonly;
1267
1648
  exports.ref = ref;
1268
- exports.resetScheduling = resetScheduling;
1269
1649
  exports.resetTracking = resetTracking;
1270
1650
  exports.shallowReactive = shallowReactive;
1651
+ exports.shallowReadArray = shallowReadArray;
1271
1652
  exports.shallowReadonly = shallowReadonly;
1272
1653
  exports.shallowRef = shallowRef;
1273
1654
  exports.stop = stop;
1274
1655
  exports.toRaw = toRaw;
1656
+ exports.toReactive = toReactive;
1657
+ exports.toReadonly = toReadonly;
1275
1658
  exports.toRef = toRef;
1276
1659
  exports.toRefs = toRefs;
1277
1660
  exports.toValue = toValue;