You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1198 lines
38 KiB
1198 lines
38 KiB
'use strict'; |
|
|
|
Object.defineProperty(exports, '__esModule', { value: true }); |
|
|
|
var shared = require('@vue/shared'); |
|
|
|
let activeEffectScope; |
|
class EffectScope { |
|
constructor(detached = false) { |
|
/** |
|
* @internal |
|
*/ |
|
this.active = true; |
|
/** |
|
* @internal |
|
*/ |
|
this.effects = []; |
|
/** |
|
* @internal |
|
*/ |
|
this.cleanups = []; |
|
if (!detached && activeEffectScope) { |
|
this.parent = activeEffectScope; |
|
this.index = |
|
(activeEffectScope.scopes || (activeEffectScope.scopes = [])).push(this) - 1; |
|
} |
|
} |
|
run(fn) { |
|
if (this.active) { |
|
const currentEffectScope = activeEffectScope; |
|
try { |
|
activeEffectScope = this; |
|
return fn(); |
|
} |
|
finally { |
|
activeEffectScope = currentEffectScope; |
|
} |
|
} |
|
} |
|
/** |
|
* This should only be called on non-detached scopes |
|
* @internal |
|
*/ |
|
on() { |
|
activeEffectScope = this; |
|
} |
|
/** |
|
* This should only be called on non-detached scopes |
|
* @internal |
|
*/ |
|
off() { |
|
activeEffectScope = this.parent; |
|
} |
|
stop(fromParent) { |
|
if (this.active) { |
|
let i, l; |
|
for (i = 0, l = this.effects.length; i < l; i++) { |
|
this.effects[i].stop(); |
|
} |
|
for (i = 0, l = this.cleanups.length; i < l; i++) { |
|
this.cleanups[i](); |
|
} |
|
if (this.scopes) { |
|
for (i = 0, l = this.scopes.length; i < l; i++) { |
|
this.scopes[i].stop(true); |
|
} |
|
} |
|
// nested scope, dereference from parent to avoid memory leaks |
|
if (this.parent && !fromParent) { |
|
// optimized O(1) removal |
|
const last = this.parent.scopes.pop(); |
|
if (last && last !== this) { |
|
this.parent.scopes[this.index] = last; |
|
last.index = this.index; |
|
} |
|
} |
|
this.active = false; |
|
} |
|
} |
|
} |
|
function effectScope(detached) { |
|
return new EffectScope(detached); |
|
} |
|
function recordEffectScope(effect, scope = activeEffectScope) { |
|
if (scope && scope.active) { |
|
scope.effects.push(effect); |
|
} |
|
} |
|
function getCurrentScope() { |
|
return activeEffectScope; |
|
} |
|
function onScopeDispose(fn) { |
|
if (activeEffectScope) { |
|
activeEffectScope.cleanups.push(fn); |
|
} |
|
} |
|
|
|
const createDep = (effects) => { |
|
const dep = new Set(effects); |
|
dep.w = 0; |
|
dep.n = 0; |
|
return dep; |
|
}; |
|
const wasTracked = (dep) => (dep.w & trackOpBit) > 0; |
|
const newTracked = (dep) => (dep.n & trackOpBit) > 0; |
|
const initDepMarkers = ({ deps }) => { |
|
if (deps.length) { |
|
for (let i = 0; i < deps.length; i++) { |
|
deps[i].w |= trackOpBit; // set was tracked |
|
} |
|
} |
|
}; |
|
const finalizeDepMarkers = (effect) => { |
|
const { deps } = effect; |
|
if (deps.length) { |
|
let ptr = 0; |
|
for (let i = 0; i < deps.length; i++) { |
|
const dep = deps[i]; |
|
if (wasTracked(dep) && !newTracked(dep)) { |
|
dep.delete(effect); |
|
} |
|
else { |
|
deps[ptr++] = dep; |
|
} |
|
// clear bits |
|
dep.w &= ~trackOpBit; |
|
dep.n &= ~trackOpBit; |
|
} |
|
deps.length = ptr; |
|
} |
|
}; |
|
|
|
const targetMap = new WeakMap(); |
|
// The number of effects currently being tracked recursively. |
|
let effectTrackDepth = 0; |
|
let trackOpBit = 1; |
|
/** |
|
* The bitwise track markers support at most 30 levels of recursion. |
|
* This value is chosen to enable modern JS engines to use a SMI on all platforms. |
|
* When recursion depth is greater, fall back to using a full cleanup. |
|
*/ |
|
const maxMarkerBits = 30; |
|
let activeEffect; |
|
const ITERATE_KEY = Symbol(''); |
|
const MAP_KEY_ITERATE_KEY = Symbol(''); |
|
class ReactiveEffect { |
|
constructor(fn, scheduler = null, scope) { |
|
this.fn = fn; |
|
this.scheduler = scheduler; |
|
this.active = true; |
|
this.deps = []; |
|
this.parent = undefined; |
|
recordEffectScope(this, scope); |
|
} |
|
run() { |
|
if (!this.active) { |
|
return this.fn(); |
|
} |
|
let parent = activeEffect; |
|
let lastShouldTrack = shouldTrack; |
|
while (parent) { |
|
if (parent === this) { |
|
return; |
|
} |
|
parent = parent.parent; |
|
} |
|
try { |
|
this.parent = activeEffect; |
|
activeEffect = this; |
|
shouldTrack = true; |
|
trackOpBit = 1 << ++effectTrackDepth; |
|
if (effectTrackDepth <= maxMarkerBits) { |
|
initDepMarkers(this); |
|
} |
|
else { |
|
cleanupEffect(this); |
|
} |
|
return this.fn(); |
|
} |
|
finally { |
|
if (effectTrackDepth <= maxMarkerBits) { |
|
finalizeDepMarkers(this); |
|
} |
|
trackOpBit = 1 << --effectTrackDepth; |
|
activeEffect = this.parent; |
|
shouldTrack = lastShouldTrack; |
|
this.parent = undefined; |
|
if (this.deferStop) { |
|
this.stop(); |
|
} |
|
} |
|
} |
|
stop() { |
|
// stopped while running itself - defer the cleanup |
|
if (activeEffect === this) { |
|
this.deferStop = true; |
|
} |
|
else if (this.active) { |
|
cleanupEffect(this); |
|
if (this.onStop) { |
|
this.onStop(); |
|
} |
|
this.active = false; |
|
} |
|
} |
|
} |
|
function cleanupEffect(effect) { |
|
const { deps } = effect; |
|
if (deps.length) { |
|
for (let i = 0; i < deps.length; i++) { |
|
deps[i].delete(effect); |
|
} |
|
deps.length = 0; |
|
} |
|
} |
|
function effect(fn, options) { |
|
if (fn.effect) { |
|
fn = fn.effect.fn; |
|
} |
|
const _effect = new ReactiveEffect(fn); |
|
if (options) { |
|
shared.extend(_effect, options); |
|
if (options.scope) |
|
recordEffectScope(_effect, options.scope); |
|
} |
|
if (!options || !options.lazy) { |
|
_effect.run(); |
|
} |
|
const runner = _effect.run.bind(_effect); |
|
runner.effect = _effect; |
|
return runner; |
|
} |
|
function stop(runner) { |
|
runner.effect.stop(); |
|
} |
|
let shouldTrack = true; |
|
const trackStack = []; |
|
function pauseTracking() { |
|
trackStack.push(shouldTrack); |
|
shouldTrack = false; |
|
} |
|
function enableTracking() { |
|
trackStack.push(shouldTrack); |
|
shouldTrack = true; |
|
} |
|
function resetTracking() { |
|
const last = trackStack.pop(); |
|
shouldTrack = last === undefined ? true : last; |
|
} |
|
function track(target, type, key) { |
|
if (shouldTrack && activeEffect) { |
|
let depsMap = targetMap.get(target); |
|
if (!depsMap) { |
|
targetMap.set(target, (depsMap = new Map())); |
|
} |
|
let dep = depsMap.get(key); |
|
if (!dep) { |
|
depsMap.set(key, (dep = createDep())); |
|
} |
|
trackEffects(dep); |
|
} |
|
} |
|
function trackEffects(dep, debuggerEventExtraInfo) { |
|
let shouldTrack = false; |
|
if (effectTrackDepth <= maxMarkerBits) { |
|
if (!newTracked(dep)) { |
|
dep.n |= trackOpBit; // set newly tracked |
|
shouldTrack = !wasTracked(dep); |
|
} |
|
} |
|
else { |
|
// Full cleanup mode. |
|
shouldTrack = !dep.has(activeEffect); |
|
} |
|
if (shouldTrack) { |
|
dep.add(activeEffect); |
|
activeEffect.deps.push(dep); |
|
} |
|
} |
|
function trigger(target, type, key, newValue, oldValue, oldTarget) { |
|
const depsMap = targetMap.get(target); |
|
if (!depsMap) { |
|
// never been tracked |
|
return; |
|
} |
|
let deps = []; |
|
if (type === "clear" /* CLEAR */) { |
|
// collection being cleared |
|
// trigger all effects for target |
|
deps = [...depsMap.values()]; |
|
} |
|
else if (key === 'length' && shared.isArray(target)) { |
|
depsMap.forEach((dep, key) => { |
|
if (key === 'length' || key >= newValue) { |
|
deps.push(dep); |
|
} |
|
}); |
|
} |
|
else { |
|
// schedule runs for SET | ADD | DELETE |
|
if (key !== void 0) { |
|
deps.push(depsMap.get(key)); |
|
} |
|
// also run for iteration key on ADD | DELETE | Map.SET |
|
switch (type) { |
|
case "add" /* ADD */: |
|
if (!shared.isArray(target)) { |
|
deps.push(depsMap.get(ITERATE_KEY)); |
|
if (shared.isMap(target)) { |
|
deps.push(depsMap.get(MAP_KEY_ITERATE_KEY)); |
|
} |
|
} |
|
else if (shared.isIntegerKey(key)) { |
|
// new index added to array -> length changes |
|
deps.push(depsMap.get('length')); |
|
} |
|
break; |
|
case "delete" /* DELETE */: |
|
if (!shared.isArray(target)) { |
|
deps.push(depsMap.get(ITERATE_KEY)); |
|
if (shared.isMap(target)) { |
|
deps.push(depsMap.get(MAP_KEY_ITERATE_KEY)); |
|
} |
|
} |
|
break; |
|
case "set" /* SET */: |
|
if (shared.isMap(target)) { |
|
deps.push(depsMap.get(ITERATE_KEY)); |
|
} |
|
break; |
|
} |
|
} |
|
if (deps.length === 1) { |
|
if (deps[0]) { |
|
{ |
|
triggerEffects(deps[0]); |
|
} |
|
} |
|
} |
|
else { |
|
const effects = []; |
|
for (const dep of deps) { |
|
if (dep) { |
|
effects.push(...dep); |
|
} |
|
} |
|
{ |
|
triggerEffects(createDep(effects)); |
|
} |
|
} |
|
} |
|
function triggerEffects(dep, debuggerEventExtraInfo) { |
|
// spread into array for stabilization |
|
const effects = shared.isArray(dep) ? dep : [...dep]; |
|
for (const effect of effects) { |
|
if (effect.computed) { |
|
triggerEffect(effect); |
|
} |
|
} |
|
for (const effect of effects) { |
|
if (!effect.computed) { |
|
triggerEffect(effect); |
|
} |
|
} |
|
} |
|
function triggerEffect(effect, debuggerEventExtraInfo) { |
|
if (effect !== activeEffect || effect.allowRecurse) { |
|
if (effect.scheduler) { |
|
effect.scheduler(); |
|
} |
|
else { |
|
effect.run(); |
|
} |
|
} |
|
} |
|
|
|
const isNonTrackableKeys = /*#__PURE__*/ shared.makeMap(`__proto__,__v_isRef,__isVue`); |
|
const builtInSymbols = new Set( |
|
/*#__PURE__*/ |
|
Object.getOwnPropertyNames(Symbol) |
|
// ios10.x Object.getOwnPropertyNames(Symbol) can enumerate 'arguments' and 'caller' |
|
// but accessing them on Symbol leads to TypeError because Symbol is a strict mode |
|
// function |
|
.filter(key => key !== 'arguments' && key !== 'caller') |
|
.map(key => Symbol[key]) |
|
.filter(shared.isSymbol)); |
|
const get = /*#__PURE__*/ createGetter(); |
|
const shallowGet = /*#__PURE__*/ createGetter(false, true); |
|
const readonlyGet = /*#__PURE__*/ createGetter(true); |
|
const shallowReadonlyGet = /*#__PURE__*/ createGetter(true, true); |
|
const arrayInstrumentations = /*#__PURE__*/ createArrayInstrumentations(); |
|
function createArrayInstrumentations() { |
|
const instrumentations = {}; |
|
['includes', 'indexOf', 'lastIndexOf'].forEach(key => { |
|
instrumentations[key] = function (...args) { |
|
const arr = toRaw(this); |
|
for (let i = 0, l = this.length; i < l; i++) { |
|
track(arr, "get" /* GET */, i + ''); |
|
} |
|
// we run the method using the original args first (which may be reactive) |
|
const res = arr[key](...args); |
|
if (res === -1 || res === false) { |
|
// if that didn't work, run it again using raw values. |
|
return arr[key](...args.map(toRaw)); |
|
} |
|
else { |
|
return res; |
|
} |
|
}; |
|
}); |
|
['push', 'pop', 'shift', 'unshift', 'splice'].forEach(key => { |
|
instrumentations[key] = function (...args) { |
|
pauseTracking(); |
|
const res = toRaw(this)[key].apply(this, args); |
|
resetTracking(); |
|
return res; |
|
}; |
|
}); |
|
return instrumentations; |
|
} |
|
function createGetter(isReadonly = false, shallow = false) { |
|
return function get(target, key, receiver) { |
|
if (key === "__v_isReactive" /* IS_REACTIVE */) { |
|
return !isReadonly; |
|
} |
|
else if (key === "__v_isReadonly" /* IS_READONLY */) { |
|
return isReadonly; |
|
} |
|
else if (key === "__v_isShallow" /* IS_SHALLOW */) { |
|
return shallow; |
|
} |
|
else if (key === "__v_raw" /* RAW */ && |
|
receiver === |
|
(isReadonly |
|
? shallow |
|
? shallowReadonlyMap |
|
: readonlyMap |
|
: shallow |
|
? shallowReactiveMap |
|
: reactiveMap).get(target)) { |
|
return target; |
|
} |
|
const targetIsArray = shared.isArray(target); |
|
if (!isReadonly && targetIsArray && shared.hasOwn(arrayInstrumentations, key)) { |
|
return Reflect.get(arrayInstrumentations, key, receiver); |
|
} |
|
const res = Reflect.get(target, key, receiver); |
|
if (shared.isSymbol(key) ? builtInSymbols.has(key) : isNonTrackableKeys(key)) { |
|
return res; |
|
} |
|
if (!isReadonly) { |
|
track(target, "get" /* GET */, key); |
|
} |
|
if (shallow) { |
|
return res; |
|
} |
|
if (isRef(res)) { |
|
// ref unwrapping - skip unwrap for Array + integer key. |
|
return targetIsArray && shared.isIntegerKey(key) ? res : res.value; |
|
} |
|
if (shared.isObject(res)) { |
|
// Convert returned value into a proxy as well. we do the isObject check |
|
// here to avoid invalid value warning. Also need to lazy access readonly |
|
// and reactive here to avoid circular dependency. |
|
return isReadonly ? readonly(res) : reactive(res); |
|
} |
|
return res; |
|
}; |
|
} |
|
const set = /*#__PURE__*/ createSetter(); |
|
const shallowSet = /*#__PURE__*/ createSetter(true); |
|
function createSetter(shallow = false) { |
|
return function set(target, key, value, receiver) { |
|
let oldValue = target[key]; |
|
if (isReadonly(oldValue) && isRef(oldValue) && !isRef(value)) { |
|
return false; |
|
} |
|
if (!shallow && !isReadonly(value)) { |
|
if (!isShallow(value)) { |
|
value = toRaw(value); |
|
oldValue = toRaw(oldValue); |
|
} |
|
if (!shared.isArray(target) && isRef(oldValue) && !isRef(value)) { |
|
oldValue.value = value; |
|
return true; |
|
} |
|
} |
|
const hadKey = shared.isArray(target) && shared.isIntegerKey(key) |
|
? Number(key) < target.length |
|
: shared.hasOwn(target, key); |
|
const result = Reflect.set(target, key, value, receiver); |
|
// don't trigger if target is something up in the prototype chain of original |
|
if (target === toRaw(receiver)) { |
|
if (!hadKey) { |
|
trigger(target, "add" /* ADD */, key, value); |
|
} |
|
else if (shared.hasChanged(value, oldValue)) { |
|
trigger(target, "set" /* SET */, key, value); |
|
} |
|
} |
|
return result; |
|
}; |
|
} |
|
function deleteProperty(target, key) { |
|
const hadKey = shared.hasOwn(target, key); |
|
target[key]; |
|
const result = Reflect.deleteProperty(target, key); |
|
if (result && hadKey) { |
|
trigger(target, "delete" /* DELETE */, key, undefined); |
|
} |
|
return result; |
|
} |
|
function has(target, key) { |
|
const result = Reflect.has(target, key); |
|
if (!shared.isSymbol(key) || !builtInSymbols.has(key)) { |
|
track(target, "has" /* HAS */, key); |
|
} |
|
return result; |
|
} |
|
function ownKeys(target) { |
|
track(target, "iterate" /* ITERATE */, shared.isArray(target) ? 'length' : ITERATE_KEY); |
|
return Reflect.ownKeys(target); |
|
} |
|
const mutableHandlers = { |
|
get, |
|
set, |
|
deleteProperty, |
|
has, |
|
ownKeys |
|
}; |
|
const readonlyHandlers = { |
|
get: readonlyGet, |
|
set(target, key) { |
|
return true; |
|
}, |
|
deleteProperty(target, key) { |
|
return true; |
|
} |
|
}; |
|
const shallowReactiveHandlers = /*#__PURE__*/ shared.extend({}, mutableHandlers, { |
|
get: shallowGet, |
|
set: shallowSet |
|
}); |
|
// Props handlers are special in the sense that it should not unwrap top-level |
|
// refs (in order to allow refs to be explicitly passed down), but should |
|
// retain the reactivity of the normal readonly object. |
|
const shallowReadonlyHandlers = /*#__PURE__*/ shared.extend({}, readonlyHandlers, { |
|
get: shallowReadonlyGet |
|
}); |
|
|
|
const toShallow = (value) => value; |
|
const getProto = (v) => Reflect.getPrototypeOf(v); |
|
function get$1(target, key, isReadonly = false, isShallow = false) { |
|
// #1772: readonly(reactive(Map)) should return readonly + reactive version |
|
// of the value |
|
target = target["__v_raw" /* RAW */]; |
|
const rawTarget = toRaw(target); |
|
const rawKey = toRaw(key); |
|
if (!isReadonly) { |
|
if (key !== rawKey) { |
|
track(rawTarget, "get" /* GET */, key); |
|
} |
|
track(rawTarget, "get" /* GET */, rawKey); |
|
} |
|
const { has } = getProto(rawTarget); |
|
const wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive; |
|
if (has.call(rawTarget, key)) { |
|
return wrap(target.get(key)); |
|
} |
|
else if (has.call(rawTarget, rawKey)) { |
|
return wrap(target.get(rawKey)); |
|
} |
|
else if (target !== rawTarget) { |
|
// #3602 readonly(reactive(Map)) |
|
// ensure that the nested reactive `Map` can do tracking for itself |
|
target.get(key); |
|
} |
|
} |
|
function has$1(key, isReadonly = false) { |
|
const target = this["__v_raw" /* RAW */]; |
|
const rawTarget = toRaw(target); |
|
const rawKey = toRaw(key); |
|
if (!isReadonly) { |
|
if (key !== rawKey) { |
|
track(rawTarget, "has" /* HAS */, key); |
|
} |
|
track(rawTarget, "has" /* HAS */, rawKey); |
|
} |
|
return key === rawKey |
|
? target.has(key) |
|
: target.has(key) || target.has(rawKey); |
|
} |
|
function size(target, isReadonly = false) { |
|
target = target["__v_raw" /* RAW */]; |
|
!isReadonly && track(toRaw(target), "iterate" /* ITERATE */, ITERATE_KEY); |
|
return Reflect.get(target, 'size', target); |
|
} |
|
function add(value) { |
|
value = toRaw(value); |
|
const target = toRaw(this); |
|
const proto = getProto(target); |
|
const hadKey = proto.has.call(target, value); |
|
if (!hadKey) { |
|
target.add(value); |
|
trigger(target, "add" /* ADD */, value, value); |
|
} |
|
return this; |
|
} |
|
function set$1(key, value) { |
|
value = toRaw(value); |
|
const target = toRaw(this); |
|
const { has, get } = getProto(target); |
|
let hadKey = has.call(target, key); |
|
if (!hadKey) { |
|
key = toRaw(key); |
|
hadKey = has.call(target, key); |
|
} |
|
const oldValue = get.call(target, key); |
|
target.set(key, value); |
|
if (!hadKey) { |
|
trigger(target, "add" /* ADD */, key, value); |
|
} |
|
else if (shared.hasChanged(value, oldValue)) { |
|
trigger(target, "set" /* SET */, key, value); |
|
} |
|
return this; |
|
} |
|
function deleteEntry(key) { |
|
const target = toRaw(this); |
|
const { has, get } = getProto(target); |
|
let hadKey = has.call(target, key); |
|
if (!hadKey) { |
|
key = toRaw(key); |
|
hadKey = has.call(target, key); |
|
} |
|
get ? get.call(target, key) : undefined; |
|
// forward the operation before queueing reactions |
|
const result = target.delete(key); |
|
if (hadKey) { |
|
trigger(target, "delete" /* DELETE */, key, undefined); |
|
} |
|
return result; |
|
} |
|
function clear() { |
|
const target = toRaw(this); |
|
const hadItems = target.size !== 0; |
|
// forward the operation before queueing reactions |
|
const result = target.clear(); |
|
if (hadItems) { |
|
trigger(target, "clear" /* CLEAR */, undefined, undefined); |
|
} |
|
return result; |
|
} |
|
function createForEach(isReadonly, isShallow) { |
|
return function forEach(callback, thisArg) { |
|
const observed = this; |
|
const target = observed["__v_raw" /* RAW */]; |
|
const rawTarget = toRaw(target); |
|
const wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive; |
|
!isReadonly && track(rawTarget, "iterate" /* ITERATE */, ITERATE_KEY); |
|
return target.forEach((value, key) => { |
|
// important: make sure the callback is |
|
// 1. invoked with the reactive map as `this` and 3rd arg |
|
// 2. the value received should be a corresponding reactive/readonly. |
|
return callback.call(thisArg, wrap(value), wrap(key), observed); |
|
}); |
|
}; |
|
} |
|
function createIterableMethod(method, isReadonly, isShallow) { |
|
return function (...args) { |
|
const target = this["__v_raw" /* RAW */]; |
|
const rawTarget = toRaw(target); |
|
const targetIsMap = shared.isMap(rawTarget); |
|
const isPair = method === 'entries' || (method === Symbol.iterator && targetIsMap); |
|
const isKeyOnly = method === 'keys' && targetIsMap; |
|
const innerIterator = target[method](...args); |
|
const wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive; |
|
!isReadonly && |
|
track(rawTarget, "iterate" /* ITERATE */, isKeyOnly ? MAP_KEY_ITERATE_KEY : ITERATE_KEY); |
|
// return a wrapped iterator which returns observed versions of the |
|
// values emitted from the real iterator |
|
return { |
|
// iterator protocol |
|
next() { |
|
const { value, done } = innerIterator.next(); |
|
return done |
|
? { value, done } |
|
: { |
|
value: isPair ? [wrap(value[0]), wrap(value[1])] : wrap(value), |
|
done |
|
}; |
|
}, |
|
// iterable protocol |
|
[Symbol.iterator]() { |
|
return this; |
|
} |
|
}; |
|
}; |
|
} |
|
function createReadonlyMethod(type) { |
|
return function (...args) { |
|
return type === "delete" /* DELETE */ ? false : this; |
|
}; |
|
} |
|
function createInstrumentations() { |
|
const mutableInstrumentations = { |
|
get(key) { |
|
return get$1(this, key); |
|
}, |
|
get size() { |
|
return size(this); |
|
}, |
|
has: has$1, |
|
add, |
|
set: set$1, |
|
delete: deleteEntry, |
|
clear, |
|
forEach: createForEach(false, false) |
|
}; |
|
const shallowInstrumentations = { |
|
get(key) { |
|
return get$1(this, key, false, true); |
|
}, |
|
get size() { |
|
return size(this); |
|
}, |
|
has: has$1, |
|
add, |
|
set: set$1, |
|
delete: deleteEntry, |
|
clear, |
|
forEach: createForEach(false, true) |
|
}; |
|
const readonlyInstrumentations = { |
|
get(key) { |
|
return get$1(this, key, true); |
|
}, |
|
get size() { |
|
return size(this, true); |
|
}, |
|
has(key) { |
|
return has$1.call(this, key, true); |
|
}, |
|
add: createReadonlyMethod("add" /* ADD */), |
|
set: createReadonlyMethod("set" /* SET */), |
|
delete: createReadonlyMethod("delete" /* DELETE */), |
|
clear: createReadonlyMethod("clear" /* CLEAR */), |
|
forEach: createForEach(true, false) |
|
}; |
|
const shallowReadonlyInstrumentations = { |
|
get(key) { |
|
return get$1(this, key, true, true); |
|
}, |
|
get size() { |
|
return size(this, true); |
|
}, |
|
has(key) { |
|
return has$1.call(this, key, true); |
|
}, |
|
add: createReadonlyMethod("add" /* ADD */), |
|
set: createReadonlyMethod("set" /* SET */), |
|
delete: createReadonlyMethod("delete" /* DELETE */), |
|
clear: createReadonlyMethod("clear" /* CLEAR */), |
|
forEach: createForEach(true, true) |
|
}; |
|
const iteratorMethods = ['keys', 'values', 'entries', Symbol.iterator]; |
|
iteratorMethods.forEach(method => { |
|
mutableInstrumentations[method] = createIterableMethod(method, false, false); |
|
readonlyInstrumentations[method] = createIterableMethod(method, true, false); |
|
shallowInstrumentations[method] = createIterableMethod(method, false, true); |
|
shallowReadonlyInstrumentations[method] = createIterableMethod(method, true, true); |
|
}); |
|
return [ |
|
mutableInstrumentations, |
|
readonlyInstrumentations, |
|
shallowInstrumentations, |
|
shallowReadonlyInstrumentations |
|
]; |
|
} |
|
const [mutableInstrumentations, readonlyInstrumentations, shallowInstrumentations, shallowReadonlyInstrumentations] = /* #__PURE__*/ createInstrumentations(); |
|
function createInstrumentationGetter(isReadonly, shallow) { |
|
const instrumentations = shallow |
|
? isReadonly |
|
? shallowReadonlyInstrumentations |
|
: shallowInstrumentations |
|
: isReadonly |
|
? readonlyInstrumentations |
|
: mutableInstrumentations; |
|
return (target, key, receiver) => { |
|
if (key === "__v_isReactive" /* IS_REACTIVE */) { |
|
return !isReadonly; |
|
} |
|
else if (key === "__v_isReadonly" /* IS_READONLY */) { |
|
return isReadonly; |
|
} |
|
else if (key === "__v_raw" /* RAW */) { |
|
return target; |
|
} |
|
return Reflect.get(shared.hasOwn(instrumentations, key) && key in target |
|
? instrumentations |
|
: target, key, receiver); |
|
}; |
|
} |
|
const mutableCollectionHandlers = { |
|
get: /*#__PURE__*/ createInstrumentationGetter(false, false) |
|
}; |
|
const shallowCollectionHandlers = { |
|
get: /*#__PURE__*/ createInstrumentationGetter(false, true) |
|
}; |
|
const readonlyCollectionHandlers = { |
|
get: /*#__PURE__*/ createInstrumentationGetter(true, false) |
|
}; |
|
const shallowReadonlyCollectionHandlers = { |
|
get: /*#__PURE__*/ createInstrumentationGetter(true, true) |
|
}; |
|
|
|
const reactiveMap = new WeakMap(); |
|
const shallowReactiveMap = new WeakMap(); |
|
const readonlyMap = new WeakMap(); |
|
const shallowReadonlyMap = new WeakMap(); |
|
function targetTypeMap(rawType) { |
|
switch (rawType) { |
|
case 'Object': |
|
case 'Array': |
|
return 1 /* COMMON */; |
|
case 'Map': |
|
case 'Set': |
|
case 'WeakMap': |
|
case 'WeakSet': |
|
return 2 /* COLLECTION */; |
|
default: |
|
return 0 /* INVALID */; |
|
} |
|
} |
|
function getTargetType(value) { |
|
return value["__v_skip" /* SKIP */] || !Object.isExtensible(value) |
|
? 0 /* INVALID */ |
|
: targetTypeMap(shared.toRawType(value)); |
|
} |
|
function reactive(target) { |
|
// if trying to observe a readonly proxy, return the readonly version. |
|
if (isReadonly(target)) { |
|
return target; |
|
} |
|
return createReactiveObject(target, false, mutableHandlers, mutableCollectionHandlers, reactiveMap); |
|
} |
|
/** |
|
* Return a shallowly-reactive copy of the original object, where only the root |
|
* level properties are reactive. It also does not auto-unwrap refs (even at the |
|
* root level). |
|
*/ |
|
function shallowReactive(target) { |
|
return createReactiveObject(target, false, shallowReactiveHandlers, shallowCollectionHandlers, shallowReactiveMap); |
|
} |
|
/** |
|
* Creates a readonly copy of the original object. Note the returned copy is not |
|
* made reactive, but `readonly` can be called on an already reactive object. |
|
*/ |
|
function readonly(target) { |
|
return createReactiveObject(target, true, readonlyHandlers, readonlyCollectionHandlers, readonlyMap); |
|
} |
|
/** |
|
* Returns a reactive-copy of the original object, where only the root level |
|
* properties are readonly, and does NOT unwrap refs nor recursively convert |
|
* returned properties. |
|
* This is used for creating the props proxy object for stateful components. |
|
*/ |
|
function shallowReadonly(target) { |
|
return createReactiveObject(target, true, shallowReadonlyHandlers, shallowReadonlyCollectionHandlers, shallowReadonlyMap); |
|
} |
|
function createReactiveObject(target, isReadonly, baseHandlers, collectionHandlers, proxyMap) { |
|
if (!shared.isObject(target)) { |
|
return target; |
|
} |
|
// target is already a Proxy, return it. |
|
// exception: calling readonly() on a reactive object |
|
if (target["__v_raw" /* RAW */] && |
|
!(isReadonly && target["__v_isReactive" /* IS_REACTIVE */])) { |
|
return target; |
|
} |
|
// target already has corresponding Proxy |
|
const existingProxy = proxyMap.get(target); |
|
if (existingProxy) { |
|
return existingProxy; |
|
} |
|
// only specific value types can be observed. |
|
const targetType = getTargetType(target); |
|
if (targetType === 0 /* INVALID */) { |
|
return target; |
|
} |
|
const proxy = new Proxy(target, targetType === 2 /* COLLECTION */ ? collectionHandlers : baseHandlers); |
|
proxyMap.set(target, proxy); |
|
return proxy; |
|
} |
|
function isReactive(value) { |
|
if (isReadonly(value)) { |
|
return isReactive(value["__v_raw" /* RAW */]); |
|
} |
|
return !!(value && value["__v_isReactive" /* IS_REACTIVE */]); |
|
} |
|
function isReadonly(value) { |
|
return !!(value && value["__v_isReadonly" /* IS_READONLY */]); |
|
} |
|
function isShallow(value) { |
|
return !!(value && value["__v_isShallow" /* IS_SHALLOW */]); |
|
} |
|
function isProxy(value) { |
|
return isReactive(value) || isReadonly(value); |
|
} |
|
function toRaw(observed) { |
|
const raw = observed && observed["__v_raw" /* RAW */]; |
|
return raw ? toRaw(raw) : observed; |
|
} |
|
function markRaw(value) { |
|
shared.def(value, "__v_skip" /* SKIP */, true); |
|
return value; |
|
} |
|
const toReactive = (value) => shared.isObject(value) ? reactive(value) : value; |
|
const toReadonly = (value) => shared.isObject(value) ? readonly(value) : value; |
|
|
|
function trackRefValue(ref) { |
|
if (shouldTrack && activeEffect) { |
|
ref = toRaw(ref); |
|
{ |
|
trackEffects(ref.dep || (ref.dep = createDep())); |
|
} |
|
} |
|
} |
|
function triggerRefValue(ref, newVal) { |
|
ref = toRaw(ref); |
|
if (ref.dep) { |
|
{ |
|
triggerEffects(ref.dep); |
|
} |
|
} |
|
} |
|
function isRef(r) { |
|
return !!(r && r.__v_isRef === true); |
|
} |
|
function ref(value) { |
|
return createRef(value, false); |
|
} |
|
function shallowRef(value) { |
|
return createRef(value, true); |
|
} |
|
function createRef(rawValue, shallow) { |
|
if (isRef(rawValue)) { |
|
return rawValue; |
|
} |
|
return new RefImpl(rawValue, shallow); |
|
} |
|
class RefImpl { |
|
constructor(value, __v_isShallow) { |
|
this.__v_isShallow = __v_isShallow; |
|
this.dep = undefined; |
|
this.__v_isRef = true; |
|
this._rawValue = __v_isShallow ? value : toRaw(value); |
|
this._value = __v_isShallow ? value : toReactive(value); |
|
} |
|
get value() { |
|
trackRefValue(this); |
|
return this._value; |
|
} |
|
set value(newVal) { |
|
newVal = this.__v_isShallow ? newVal : toRaw(newVal); |
|
if (shared.hasChanged(newVal, this._rawValue)) { |
|
this._rawValue = newVal; |
|
this._value = this.__v_isShallow ? newVal : toReactive(newVal); |
|
triggerRefValue(this); |
|
} |
|
} |
|
} |
|
function triggerRef(ref) { |
|
triggerRefValue(ref); |
|
} |
|
function unref(ref) { |
|
return isRef(ref) ? ref.value : ref; |
|
} |
|
const shallowUnwrapHandlers = { |
|
get: (target, key, receiver) => unref(Reflect.get(target, key, receiver)), |
|
set: (target, key, value, receiver) => { |
|
const oldValue = target[key]; |
|
if (isRef(oldValue) && !isRef(value)) { |
|
oldValue.value = value; |
|
return true; |
|
} |
|
else { |
|
return Reflect.set(target, key, value, receiver); |
|
} |
|
} |
|
}; |
|
function proxyRefs(objectWithRefs) { |
|
return isReactive(objectWithRefs) |
|
? objectWithRefs |
|
: new Proxy(objectWithRefs, shallowUnwrapHandlers); |
|
} |
|
class CustomRefImpl { |
|
constructor(factory) { |
|
this.dep = undefined; |
|
this.__v_isRef = true; |
|
const { get, set } = factory(() => trackRefValue(this), () => triggerRefValue(this)); |
|
this._get = get; |
|
this._set = set; |
|
} |
|
get value() { |
|
return this._get(); |
|
} |
|
set value(newVal) { |
|
this._set(newVal); |
|
} |
|
} |
|
function customRef(factory) { |
|
return new CustomRefImpl(factory); |
|
} |
|
function toRefs(object) { |
|
const ret = shared.isArray(object) ? new Array(object.length) : {}; |
|
for (const key in object) { |
|
ret[key] = toRef(object, key); |
|
} |
|
return ret; |
|
} |
|
class ObjectRefImpl { |
|
constructor(_object, _key, _defaultValue) { |
|
this._object = _object; |
|
this._key = _key; |
|
this._defaultValue = _defaultValue; |
|
this.__v_isRef = true; |
|
} |
|
get value() { |
|
const val = this._object[this._key]; |
|
return val === undefined ? this._defaultValue : val; |
|
} |
|
set value(newVal) { |
|
this._object[this._key] = newVal; |
|
} |
|
} |
|
function toRef(object, key, defaultValue) { |
|
const val = object[key]; |
|
return isRef(val) |
|
? val |
|
: new ObjectRefImpl(object, key, defaultValue); |
|
} |
|
|
|
class ComputedRefImpl { |
|
constructor(getter, _setter, isReadonly, isSSR) { |
|
this._setter = _setter; |
|
this.dep = undefined; |
|
this.__v_isRef = true; |
|
this._dirty = true; |
|
this.effect = new ReactiveEffect(getter, () => { |
|
if (!this._dirty) { |
|
this._dirty = true; |
|
triggerRefValue(this); |
|
} |
|
}); |
|
this.effect.computed = this; |
|
this.effect.active = this._cacheable = !isSSR; |
|
this["__v_isReadonly" /* IS_READONLY */] = isReadonly; |
|
} |
|
get value() { |
|
// the computed ref may get wrapped by other proxies e.g. readonly() #3376 |
|
const self = toRaw(this); |
|
trackRefValue(self); |
|
if (self._dirty || !self._cacheable) { |
|
self._dirty = false; |
|
self._value = self.effect.run(); |
|
} |
|
return self._value; |
|
} |
|
set value(newValue) { |
|
this._setter(newValue); |
|
} |
|
} |
|
function computed(getterOrOptions, debugOptions, isSSR = false) { |
|
let getter; |
|
let setter; |
|
const onlyGetter = shared.isFunction(getterOrOptions); |
|
if (onlyGetter) { |
|
getter = getterOrOptions; |
|
setter = shared.NOOP; |
|
} |
|
else { |
|
getter = getterOrOptions.get; |
|
setter = getterOrOptions.set; |
|
} |
|
const cRef = new ComputedRefImpl(getter, setter, onlyGetter || !setter, isSSR); |
|
return cRef; |
|
} |
|
|
|
var _a; |
|
const tick = /*#__PURE__*/ Promise.resolve(); |
|
const queue = []; |
|
let queued = false; |
|
const scheduler = (fn) => { |
|
queue.push(fn); |
|
if (!queued) { |
|
queued = true; |
|
tick.then(flush); |
|
} |
|
}; |
|
const flush = () => { |
|
for (let i = 0; i < queue.length; i++) { |
|
queue[i](); |
|
} |
|
queue.length = 0; |
|
queued = false; |
|
}; |
|
class DeferredComputedRefImpl { |
|
constructor(getter) { |
|
this.dep = undefined; |
|
this._dirty = true; |
|
this.__v_isRef = true; |
|
this[_a] = true; |
|
let compareTarget; |
|
let hasCompareTarget = false; |
|
let scheduled = false; |
|
this.effect = new ReactiveEffect(getter, (computedTrigger) => { |
|
if (this.dep) { |
|
if (computedTrigger) { |
|
compareTarget = this._value; |
|
hasCompareTarget = true; |
|
} |
|
else if (!scheduled) { |
|
const valueToCompare = hasCompareTarget ? compareTarget : this._value; |
|
scheduled = true; |
|
hasCompareTarget = false; |
|
scheduler(() => { |
|
if (this.effect.active && this._get() !== valueToCompare) { |
|
triggerRefValue(this); |
|
} |
|
scheduled = false; |
|
}); |
|
} |
|
// chained upstream computeds are notified synchronously to ensure |
|
// value invalidation in case of sync access; normal effects are |
|
// deferred to be triggered in scheduler. |
|
for (const e of this.dep) { |
|
if (e.computed instanceof DeferredComputedRefImpl) { |
|
e.scheduler(true /* computedTrigger */); |
|
} |
|
} |
|
} |
|
this._dirty = true; |
|
}); |
|
this.effect.computed = this; |
|
} |
|
_get() { |
|
if (this._dirty) { |
|
this._dirty = false; |
|
return (this._value = this.effect.run()); |
|
} |
|
return this._value; |
|
} |
|
get value() { |
|
trackRefValue(this); |
|
// the computed ref may get wrapped by other proxies e.g. readonly() #3376 |
|
return toRaw(this)._get(); |
|
} |
|
} |
|
_a = "__v_isReadonly" /* IS_READONLY */; |
|
function deferredComputed(getter) { |
|
return new DeferredComputedRefImpl(getter); |
|
} |
|
|
|
exports.EffectScope = EffectScope; |
|
exports.ITERATE_KEY = ITERATE_KEY; |
|
exports.ReactiveEffect = ReactiveEffect; |
|
exports.computed = computed; |
|
exports.customRef = customRef; |
|
exports.deferredComputed = deferredComputed; |
|
exports.effect = effect; |
|
exports.effectScope = effectScope; |
|
exports.enableTracking = enableTracking; |
|
exports.getCurrentScope = getCurrentScope; |
|
exports.isProxy = isProxy; |
|
exports.isReactive = isReactive; |
|
exports.isReadonly = isReadonly; |
|
exports.isRef = isRef; |
|
exports.isShallow = isShallow; |
|
exports.markRaw = markRaw; |
|
exports.onScopeDispose = onScopeDispose; |
|
exports.pauseTracking = pauseTracking; |
|
exports.proxyRefs = proxyRefs; |
|
exports.reactive = reactive; |
|
exports.readonly = readonly; |
|
exports.ref = ref; |
|
exports.resetTracking = resetTracking; |
|
exports.shallowReactive = shallowReactive; |
|
exports.shallowReadonly = shallowReadonly; |
|
exports.shallowRef = shallowRef; |
|
exports.stop = stop; |
|
exports.toRaw = toRaw; |
|
exports.toRef = toRef; |
|
exports.toRefs = toRefs; |
|
exports.track = track; |
|
exports.trigger = trigger; |
|
exports.triggerRef = triggerRef; |
|
exports.unref = unref;
|
|
|