@vue/reactivity 3.4.25 → 3.5.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @vue/reactivity v3.4.25
2
+ * @vue/reactivity v3.5.0-alpha.1
3
3
  * (c) 2018-present Yuxi (Evan) You and Vue contributors
4
4
  * @license MIT
5
5
  **/
@@ -95,157 +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
- var _a;
191
- if (this.active) {
192
- preCleanupEffect(this);
193
- postCleanupEffect(this);
194
- (_a = this.onStop) == null ? void 0 : _a.call(this);
195
- this.active = false;
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);
204
+ this.onStop && this.onStop();
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();
196
221
  }
197
222
  }
223
+ get dirty() {
224
+ return isDirty(this);
225
+ }
198
226
  }
199
- function triggerComputed(computed) {
200
- return computed.value;
227
+ let batchDepth = 0;
228
+ let batchedEffect;
229
+ function startBatch() {
230
+ batchDepth++;
201
231
  }
202
- function preCleanupEffect(effect2) {
203
- effect2._trackId++;
204
- 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;
205
284
  }
206
- function postCleanupEffect(effect2) {
207
- if (effect2.deps.length > effect2._depsLength) {
208
- for (let i = effect2._depsLength; i < effect2.deps.length; i++) {
209
- 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;
210
289
  }
211
- effect2.deps.length = effect2._depsLength;
212
290
  }
291
+ if (sub._dirty) {
292
+ return true;
293
+ }
294
+ return false;
213
295
  }
214
- function cleanupDepEffect(dep, effect2) {
215
- const trackId = dep.get(effect2);
216
- if (trackId !== void 0 && effect2._trackId !== trackId) {
217
- dep.delete(effect2);
218
- if (dep.size === 0) {
219
- 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);
220
352
  }
221
353
  }
222
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
+ }
223
366
  function effect(fn, options) {
224
367
  if (fn.effect instanceof ReactiveEffect) {
225
368
  fn = fn.effect.fn;
226
369
  }
227
- const _effect = new ReactiveEffect(fn, shared.NOOP, () => {
228
- if (_effect.dirty) {
229
- _effect.run();
230
- }
231
- });
370
+ const e = new ReactiveEffect(fn);
232
371
  if (options) {
233
- shared.extend(_effect, options);
234
- if (options.scope)
235
- recordEffectScope(_effect, options.scope);
372
+ shared.extend(e, options);
236
373
  }
237
- if (!options || !options.lazy) {
238
- _effect.run();
374
+ try {
375
+ e.run();
376
+ } catch (err) {
377
+ e.stop();
378
+ throw err;
239
379
  }
240
- const runner = _effect.run.bind(_effect);
241
- runner.effect = _effect;
380
+ const runner = e.run.bind(e);
381
+ runner.effect = e;
242
382
  return runner;
243
383
  }
244
384
  function stop(runner) {
245
385
  runner.effect.stop();
246
386
  }
247
387
  let shouldTrack = true;
248
- let pauseScheduleStack = 0;
249
388
  const trackStack = [];
250
389
  function pauseTracking() {
251
390
  trackStack.push(shouldTrack);
@@ -259,192 +398,423 @@ function resetTracking() {
259
398
  const last = trackStack.pop();
260
399
  shouldTrack = last === void 0 ? true : last;
261
400
  }
262
- function pauseScheduling() {
263
- pauseScheduleStack++;
264
- }
265
- function resetScheduling() {
266
- pauseScheduleStack--;
267
- while (!pauseScheduleStack && queueEffectSchedulers.length) {
268
- 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
+ );
269
408
  }
270
409
  }
271
- function trackEffect(effect2, dep, debuggerEventExtraInfo) {
272
- var _a;
273
- if (dep.get(effect2) !== effect2._trackId) {
274
- dep.set(effect2, effect2._trackId);
275
- const oldDep = effect2.deps[effect2._depsLength];
276
- if (oldDep !== dep) {
277
- if (oldDep) {
278
- cleanupDepEffect(oldDep, effect2);
279
- }
280
- effect2.deps[effect2._depsLength++] = dep;
281
- } else {
282
- 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;
283
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;
284
437
  {
285
- (_a = effect2.onTrack) == null ? void 0 : _a.call(effect2, shared.extend({ effect: effect2 }, debuggerEventExtraInfo));
438
+ this.subsHead = void 0;
286
439
  }
287
440
  }
288
- }
289
- const queueEffectSchedulers = [];
290
- function triggerEffects(dep, dirtyLevel, debuggerEventExtraInfo) {
291
- var _a;
292
- pauseScheduling();
293
- for (const effect2 of dep.keys()) {
294
- let tracking;
295
- if (effect2._dirtyLevel < dirtyLevel && (tracking != null ? tracking : tracking = dep.get(effect2) === effect2._trackId)) {
296
- effect2._shouldSchedule || (effect2._shouldSchedule = effect2._dirtyLevel === 0);
297
- effect2._dirtyLevel = dirtyLevel;
441
+ track(debugInfo) {
442
+ if (!activeSub || !shouldTrack) {
443
+ return;
298
444
  }
299
- if (effect2._shouldSchedule && (tracking != null ? tracking : tracking = dep.get(effect2) === effect2._trackId)) {
300
- {
301
- (_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
+ }
302
482
  }
303
- effect2.trigger();
304
- if ((!effect2._runnings || effect2.allowRecurse) && effect2._dirtyLevel !== 2) {
305
- effect2._shouldSchedule = false;
306
- if (effect2.scheduler) {
307
- 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
+ }
308
516
  }
309
517
  }
518
+ for (let link = this.subs; link; link = link.prevSub) {
519
+ link.sub.notify();
520
+ }
521
+ } finally {
522
+ endBatch();
310
523
  }
311
524
  }
312
- resetScheduling();
313
525
  }
314
-
315
- const createDep = (cleanup, computed) => {
316
- const dep = /* @__PURE__ */ new Map();
317
- dep.cleanup = cleanup;
318
- dep.computed = computed;
319
- return dep;
320
- };
321
-
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
+ }
322
545
  const targetMap = /* @__PURE__ */ new WeakMap();
323
- const ITERATE_KEY = Symbol("iterate" );
324
- 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" );
325
549
  function track(target, type, key) {
326
- if (shouldTrack && activeEffect) {
550
+ if (shouldTrack && activeSub) {
327
551
  let depsMap = targetMap.get(target);
328
552
  if (!depsMap) {
329
553
  targetMap.set(target, depsMap = /* @__PURE__ */ new Map());
330
554
  }
331
555
  let dep = depsMap.get(key);
332
556
  if (!dep) {
333
- depsMap.set(key, dep = createDep(() => depsMap.delete(key)));
557
+ depsMap.set(key, dep = new Dep());
334
558
  }
335
- trackEffect(
336
- activeEffect,
337
- dep,
338
- {
559
+ {
560
+ dep.track({
339
561
  target,
340
562
  type,
341
563
  key
342
- }
343
- );
564
+ });
565
+ }
344
566
  }
345
567
  }
346
568
  function trigger(target, type, key, newValue, oldValue, oldTarget) {
347
569
  const depsMap = targetMap.get(target);
348
570
  if (!depsMap) {
571
+ globalVersion++;
349
572
  return;
350
573
  }
351
574
  let deps = [];
352
575
  if (type === "clear") {
353
576
  deps = [...depsMap.values()];
354
- } else if (key === "length" && shared.isArray(target)) {
355
- const newLength = Number(newValue);
356
- depsMap.forEach((dep, key2) => {
357
- if (key2 === "length" || !shared.isSymbol(key2) && key2 >= newLength) {
358
- deps.push(dep);
359
- }
360
- });
361
577
  } else {
362
- if (key !== void 0) {
363
- deps.push(depsMap.get(key));
364
- }
365
- switch (type) {
366
- case "add":
367
- if (!shared.isArray(target)) {
368
- deps.push(depsMap.get(ITERATE_KEY));
369
- if (shared.isMap(target)) {
370
- deps.push(depsMap.get(MAP_KEY_ITERATE_KEY));
371
- }
372
- } else if (shared.isIntegerKey(key)) {
373
- 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);
374
585
  }
375
- break;
376
- case "delete":
377
- if (!shared.isArray(target)) {
378
- 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":
379
615
  if (shared.isMap(target)) {
380
- deps.push(depsMap.get(MAP_KEY_ITERATE_KEY));
616
+ push(depsMap.get(ITERATE_KEY));
381
617
  }
382
- }
383
- break;
384
- case "set":
385
- if (shared.isMap(target)) {
386
- deps.push(depsMap.get(ITERATE_KEY));
387
- }
388
- break;
618
+ break;
619
+ }
389
620
  }
390
621
  }
391
- pauseScheduling();
622
+ startBatch();
392
623
  for (const dep of deps) {
393
- if (dep) {
394
- triggerEffects(
395
- dep,
396
- 4,
397
- {
398
- target,
399
- type,
400
- key,
401
- newValue,
402
- oldValue,
403
- oldTarget
404
- }
405
- );
624
+ {
625
+ dep.trigger({
626
+ target,
627
+ type,
628
+ key,
629
+ newValue,
630
+ oldValue,
631
+ oldTarget
632
+ });
406
633
  }
407
634
  }
408
- resetScheduling();
635
+ endBatch();
409
636
  }
410
637
  function getDepFromReactive(object, key) {
411
638
  var _a;
412
639
  return (_a = targetMap.get(object)) == null ? void 0 : _a.get(key);
413
640
  }
414
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;
812
+ }
813
+
415
814
  const isNonTrackableKeys = /* @__PURE__ */ shared.makeMap(`__proto__,__v_isRef,__isVue`);
416
815
  const builtInSymbols = new Set(
417
816
  /* @__PURE__ */ Object.getOwnPropertyNames(Symbol).filter((key) => key !== "arguments" && key !== "caller").map((key) => Symbol[key]).filter(shared.isSymbol)
418
817
  );
419
- const arrayInstrumentations = /* @__PURE__ */ createArrayInstrumentations();
420
- function createArrayInstrumentations() {
421
- const instrumentations = {};
422
- ["includes", "indexOf", "lastIndexOf"].forEach((key) => {
423
- instrumentations[key] = function(...args) {
424
- const arr = toRaw(this);
425
- for (let i = 0, l = this.length; i < l; i++) {
426
- track(arr, "get", i + "");
427
- }
428
- const res = arr[key](...args);
429
- if (res === -1 || res === false) {
430
- return arr[key](...args.map(toRaw));
431
- } else {
432
- return res;
433
- }
434
- };
435
- });
436
- ["push", "pop", "shift", "unshift", "splice"].forEach((key) => {
437
- instrumentations[key] = function(...args) {
438
- pauseTracking();
439
- pauseScheduling();
440
- const res = toRaw(this)[key].apply(this, args);
441
- resetScheduling();
442
- resetTracking();
443
- return res;
444
- };
445
- });
446
- return instrumentations;
447
- }
448
818
  function hasOwnProperty(key) {
449
819
  if (!shared.isSymbol(key))
450
820
  key = String(key);
@@ -475,14 +845,22 @@ class BaseReactiveHandler {
475
845
  }
476
846
  const targetIsArray = shared.isArray(target);
477
847
  if (!isReadonly2) {
478
- if (targetIsArray && shared.hasOwn(arrayInstrumentations, key)) {
479
- return Reflect.get(arrayInstrumentations, key, receiver);
848
+ let fn;
849
+ if (targetIsArray && (fn = arrayInstrumentations[key])) {
850
+ return fn;
480
851
  }
481
852
  if (key === "hasOwnProperty") {
482
853
  return hasOwnProperty;
483
854
  }
484
855
  }
485
- 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
+ );
486
864
  if (shared.isSymbol(key) ? builtInSymbols.has(key) : isNonTrackableKeys(key)) {
487
865
  return res;
488
866
  }
@@ -981,110 +1359,8 @@ function markRaw(value) {
981
1359
  const toReactive = (value) => shared.isObject(value) ? reactive(value) : value;
982
1360
  const toReadonly = (value) => shared.isObject(value) ? readonly(value) : value;
983
1361
 
984
- 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`;
985
- class ComputedRefImpl {
986
- constructor(getter, _setter, isReadonly, isSSR) {
987
- this.getter = getter;
988
- this._setter = _setter;
989
- this.dep = void 0;
990
- this.__v_isRef = true;
991
- this["__v_isReadonly"] = false;
992
- this.effect = new ReactiveEffect(
993
- () => getter(this._value),
994
- () => triggerRefValue(
995
- this,
996
- this.effect._dirtyLevel === 2 ? 2 : 3
997
- )
998
- );
999
- this.effect.computed = this;
1000
- this.effect.active = this._cacheable = !isSSR;
1001
- this["__v_isReadonly"] = isReadonly;
1002
- }
1003
- get value() {
1004
- const self = toRaw(this);
1005
- if ((!self._cacheable || self.effect.dirty) && shared.hasChanged(self._value, self._value = self.effect.run())) {
1006
- triggerRefValue(self, 4);
1007
- }
1008
- trackRefValue(self);
1009
- if (self.effect._dirtyLevel >= 2) {
1010
- if (this._warnRecursive) {
1011
- warn(COMPUTED_SIDE_EFFECT_WARN, `
1012
-
1013
- getter: `, this.getter);
1014
- }
1015
- triggerRefValue(self, 2);
1016
- }
1017
- return self._value;
1018
- }
1019
- set value(newValue) {
1020
- this._setter(newValue);
1021
- }
1022
- // #region polyfill _dirty for backward compatibility third party code for Vue <= 3.3.x
1023
- get _dirty() {
1024
- return this.effect.dirty;
1025
- }
1026
- set _dirty(v) {
1027
- this.effect.dirty = v;
1028
- }
1029
- // #endregion
1030
- }
1031
- function computed(getterOrOptions, debugOptions, isSSR = false) {
1032
- let getter;
1033
- let setter;
1034
- const onlyGetter = shared.isFunction(getterOrOptions);
1035
- if (onlyGetter) {
1036
- getter = getterOrOptions;
1037
- setter = () => {
1038
- warn("Write operation failed: computed value is readonly");
1039
- } ;
1040
- } else {
1041
- getter = getterOrOptions.get;
1042
- setter = getterOrOptions.set;
1043
- }
1044
- const cRef = new ComputedRefImpl(getter, setter, onlyGetter || !setter, isSSR);
1045
- if (debugOptions && !isSSR) {
1046
- cRef.effect.onTrack = debugOptions.onTrack;
1047
- cRef.effect.onTrigger = debugOptions.onTrigger;
1048
- }
1049
- return cRef;
1050
- }
1051
-
1052
- function trackRefValue(ref2) {
1053
- var _a;
1054
- if (shouldTrack && activeEffect) {
1055
- ref2 = toRaw(ref2);
1056
- trackEffect(
1057
- activeEffect,
1058
- (_a = ref2.dep) != null ? _a : ref2.dep = createDep(
1059
- () => ref2.dep = void 0,
1060
- ref2 instanceof ComputedRefImpl ? ref2 : void 0
1061
- ),
1062
- {
1063
- target: ref2,
1064
- type: "get",
1065
- key: "value"
1066
- }
1067
- );
1068
- }
1069
- }
1070
- function triggerRefValue(ref2, dirtyLevel = 4, newVal) {
1071
- ref2 = toRaw(ref2);
1072
- const dep = ref2.dep;
1073
- if (dep) {
1074
- triggerEffects(
1075
- dep,
1076
- dirtyLevel,
1077
- {
1078
- target: ref2,
1079
- type: "set",
1080
- key: "value",
1081
- newValue: newVal
1082
- }
1083
- );
1084
- }
1085
- }
1086
1362
  function isRef(r) {
1087
- return !!(r && r.__v_isRef === true);
1363
+ return r ? r.__v_isRef === true : false;
1088
1364
  }
1089
1365
  function ref(value) {
1090
1366
  return createRef(value, false);
@@ -1101,27 +1377,49 @@ function createRef(rawValue, shallow) {
1101
1377
  class RefImpl {
1102
1378
  constructor(value, __v_isShallow) {
1103
1379
  this.__v_isShallow = __v_isShallow;
1104
- this.dep = void 0;
1380
+ this.dep = new Dep();
1105
1381
  this.__v_isRef = true;
1106
1382
  this._rawValue = __v_isShallow ? value : toRaw(value);
1107
1383
  this._value = __v_isShallow ? value : toReactive(value);
1108
1384
  }
1109
1385
  get value() {
1110
- trackRefValue(this);
1386
+ {
1387
+ this.dep.track({
1388
+ target: this,
1389
+ type: "get",
1390
+ key: "value"
1391
+ });
1392
+ }
1111
1393
  return this._value;
1112
1394
  }
1113
- set value(newVal) {
1114
- const useDirectValue = this.__v_isShallow || isShallow(newVal) || isReadonly(newVal);
1115
- newVal = useDirectValue ? newVal : toRaw(newVal);
1116
- if (shared.hasChanged(newVal, this._rawValue)) {
1117
- this._rawValue = newVal;
1118
- this._value = useDirectValue ? newVal : toReactive(newVal);
1119
- 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
+ }
1120
1411
  }
1121
1412
  }
1122
1413
  }
1123
1414
  function triggerRef(ref2) {
1124
- 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
+ }
1125
1423
  }
1126
1424
  function unref(ref2) {
1127
1425
  return isRef(ref2) ? ref2.value : ref2;
@@ -1146,12 +1444,9 @@ function proxyRefs(objectWithRefs) {
1146
1444
  }
1147
1445
  class CustomRefImpl {
1148
1446
  constructor(factory) {
1149
- this.dep = void 0;
1150
1447
  this.__v_isRef = true;
1151
- const { get, set } = factory(
1152
- () => trackRefValue(this),
1153
- () => triggerRefValue(this)
1154
- );
1448
+ const dep = this.dep = new Dep();
1449
+ const { get, set } = factory(dep.track.bind(dep), dep.trigger.bind(dep));
1155
1450
  this._get = get;
1156
1451
  this._set = set;
1157
1452
  }
@@ -1219,7 +1514,89 @@ function propertyToRef(source, key, defaultValue) {
1219
1514
  return isRef(val) ? val : new ObjectRefImpl(source, key, defaultValue);
1220
1515
  }
1221
1516
 
1222
- 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
+ }
1223
1600
 
1224
1601
  const TrackOpTypes = {
1225
1602
  "GET": "get",
@@ -1240,15 +1617,17 @@ const ReactiveFlags = {
1240
1617
  "RAW": "__v_raw"
1241
1618
  };
1242
1619
 
1620
+ exports.ARRAY_ITERATE_KEY = ARRAY_ITERATE_KEY;
1621
+ exports.EffectFlags = EffectFlags;
1243
1622
  exports.EffectScope = EffectScope;
1244
1623
  exports.ITERATE_KEY = ITERATE_KEY;
1624
+ exports.MAP_KEY_ITERATE_KEY = MAP_KEY_ITERATE_KEY;
1245
1625
  exports.ReactiveEffect = ReactiveEffect;
1246
1626
  exports.ReactiveFlags = ReactiveFlags;
1247
1627
  exports.TrackOpTypes = TrackOpTypes;
1248
1628
  exports.TriggerOpTypes = TriggerOpTypes;
1249
1629
  exports.computed = computed;
1250
1630
  exports.customRef = customRef;
1251
- exports.deferredComputed = deferredComputed;
1252
1631
  exports.effect = effect;
1253
1632
  exports.effectScope = effectScope;
1254
1633
  exports.enableTracking = enableTracking;
@@ -1259,20 +1638,23 @@ exports.isReadonly = isReadonly;
1259
1638
  exports.isRef = isRef;
1260
1639
  exports.isShallow = isShallow;
1261
1640
  exports.markRaw = markRaw;
1641
+ exports.onEffectCleanup = onEffectCleanup;
1262
1642
  exports.onScopeDispose = onScopeDispose;
1263
- exports.pauseScheduling = pauseScheduling;
1264
1643
  exports.pauseTracking = pauseTracking;
1265
1644
  exports.proxyRefs = proxyRefs;
1266
1645
  exports.reactive = reactive;
1646
+ exports.reactiveReadArray = reactiveReadArray;
1267
1647
  exports.readonly = readonly;
1268
1648
  exports.ref = ref;
1269
- exports.resetScheduling = resetScheduling;
1270
1649
  exports.resetTracking = resetTracking;
1271
1650
  exports.shallowReactive = shallowReactive;
1651
+ exports.shallowReadArray = shallowReadArray;
1272
1652
  exports.shallowReadonly = shallowReadonly;
1273
1653
  exports.shallowRef = shallowRef;
1274
1654
  exports.stop = stop;
1275
1655
  exports.toRaw = toRaw;
1656
+ exports.toReactive = toReactive;
1657
+ exports.toReadonly = toReadonly;
1276
1658
  exports.toRef = toRef;
1277
1659
  exports.toRefs = toRefs;
1278
1660
  exports.toValue = toValue;