reactivity.esm-bundler.js 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197
  1. import { extend, isArray, isMap, isIntegerKey, isSymbol, hasOwn, isObject, hasChanged, makeMap, capitalize, toRawType, def, isFunction, NOOP } from '@vue/shared';
  2. function warn(msg, ...args) {
  3. console.warn(`[Vue warn] ${msg}`, ...args);
  4. }
  5. let activeEffectScope;
  6. const effectScopeStack = [];
  7. class EffectScope {
  8. constructor(detached = false) {
  9. this.active = true;
  10. this.effects = [];
  11. this.cleanups = [];
  12. if (!detached && activeEffectScope) {
  13. this.parent = activeEffectScope;
  14. this.index =
  15. (activeEffectScope.scopes || (activeEffectScope.scopes = [])).push(this) - 1;
  16. }
  17. }
  18. run(fn) {
  19. if (this.active) {
  20. try {
  21. this.on();
  22. return fn();
  23. }
  24. finally {
  25. this.off();
  26. }
  27. }
  28. else if ((process.env.NODE_ENV !== 'production')) {
  29. warn(`cannot run an inactive effect scope.`);
  30. }
  31. }
  32. on() {
  33. if (this.active) {
  34. effectScopeStack.push(this);
  35. activeEffectScope = this;
  36. }
  37. }
  38. off() {
  39. if (this.active) {
  40. effectScopeStack.pop();
  41. activeEffectScope = effectScopeStack[effectScopeStack.length - 1];
  42. }
  43. }
  44. stop(fromParent) {
  45. if (this.active) {
  46. this.effects.forEach(e => e.stop());
  47. this.cleanups.forEach(cleanup => cleanup());
  48. if (this.scopes) {
  49. this.scopes.forEach(e => e.stop(true));
  50. }
  51. // nested scope, dereference from parent to avoid memory leaks
  52. if (this.parent && !fromParent) {
  53. // optimized O(1) removal
  54. const last = this.parent.scopes.pop();
  55. if (last && last !== this) {
  56. this.parent.scopes[this.index] = last;
  57. last.index = this.index;
  58. }
  59. }
  60. this.active = false;
  61. }
  62. }
  63. }
  64. function effectScope(detached) {
  65. return new EffectScope(detached);
  66. }
  67. function recordEffectScope(effect, scope) {
  68. scope = scope || activeEffectScope;
  69. if (scope && scope.active) {
  70. scope.effects.push(effect);
  71. }
  72. }
  73. function getCurrentScope() {
  74. return activeEffectScope;
  75. }
  76. function onScopeDispose(fn) {
  77. if (activeEffectScope) {
  78. activeEffectScope.cleanups.push(fn);
  79. }
  80. else if ((process.env.NODE_ENV !== 'production')) {
  81. warn(`onScopeDispose() is called when there is no active effect scope` +
  82. ` to be associated with.`);
  83. }
  84. }
  85. const createDep = (effects) => {
  86. const dep = new Set(effects);
  87. dep.w = 0;
  88. dep.n = 0;
  89. return dep;
  90. };
  91. const wasTracked = (dep) => (dep.w & trackOpBit) > 0;
  92. const newTracked = (dep) => (dep.n & trackOpBit) > 0;
  93. const initDepMarkers = ({ deps }) => {
  94. if (deps.length) {
  95. for (let i = 0; i < deps.length; i++) {
  96. deps[i].w |= trackOpBit; // set was tracked
  97. }
  98. }
  99. };
  100. const finalizeDepMarkers = (effect) => {
  101. const { deps } = effect;
  102. if (deps.length) {
  103. let ptr = 0;
  104. for (let i = 0; i < deps.length; i++) {
  105. const dep = deps[i];
  106. if (wasTracked(dep) && !newTracked(dep)) {
  107. dep.delete(effect);
  108. }
  109. else {
  110. deps[ptr++] = dep;
  111. }
  112. // clear bits
  113. dep.w &= ~trackOpBit;
  114. dep.n &= ~trackOpBit;
  115. }
  116. deps.length = ptr;
  117. }
  118. };
  119. const targetMap = new WeakMap();
  120. // The number of effects currently being tracked recursively.
  121. let effectTrackDepth = 0;
  122. let trackOpBit = 1;
  123. /**
  124. * The bitwise track markers support at most 30 levels of recursion.
  125. * This value is chosen to enable modern JS engines to use a SMI on all platforms.
  126. * When recursion depth is greater, fall back to using a full cleanup.
  127. */
  128. const maxMarkerBits = 30;
  129. const effectStack = [];
  130. let activeEffect;
  131. const ITERATE_KEY = Symbol((process.env.NODE_ENV !== 'production') ? 'iterate' : '');
  132. const MAP_KEY_ITERATE_KEY = Symbol((process.env.NODE_ENV !== 'production') ? 'Map key iterate' : '');
  133. class ReactiveEffect {
  134. constructor(fn, scheduler = null, scope) {
  135. this.fn = fn;
  136. this.scheduler = scheduler;
  137. this.active = true;
  138. this.deps = [];
  139. recordEffectScope(this, scope);
  140. }
  141. run() {
  142. if (!this.active) {
  143. return this.fn();
  144. }
  145. if (!effectStack.includes(this)) {
  146. try {
  147. effectStack.push((activeEffect = this));
  148. enableTracking();
  149. trackOpBit = 1 << ++effectTrackDepth;
  150. if (effectTrackDepth <= maxMarkerBits) {
  151. initDepMarkers(this);
  152. }
  153. else {
  154. cleanupEffect(this);
  155. }
  156. return this.fn();
  157. }
  158. finally {
  159. if (effectTrackDepth <= maxMarkerBits) {
  160. finalizeDepMarkers(this);
  161. }
  162. trackOpBit = 1 << --effectTrackDepth;
  163. resetTracking();
  164. effectStack.pop();
  165. const n = effectStack.length;
  166. activeEffect = n > 0 ? effectStack[n - 1] : undefined;
  167. }
  168. }
  169. }
  170. stop() {
  171. if (this.active) {
  172. cleanupEffect(this);
  173. if (this.onStop) {
  174. this.onStop();
  175. }
  176. this.active = false;
  177. }
  178. }
  179. }
  180. function cleanupEffect(effect) {
  181. const { deps } = effect;
  182. if (deps.length) {
  183. for (let i = 0; i < deps.length; i++) {
  184. deps[i].delete(effect);
  185. }
  186. deps.length = 0;
  187. }
  188. }
  189. function effect(fn, options) {
  190. if (fn.effect) {
  191. fn = fn.effect.fn;
  192. }
  193. const _effect = new ReactiveEffect(fn);
  194. if (options) {
  195. extend(_effect, options);
  196. if (options.scope)
  197. recordEffectScope(_effect, options.scope);
  198. }
  199. if (!options || !options.lazy) {
  200. _effect.run();
  201. }
  202. const runner = _effect.run.bind(_effect);
  203. runner.effect = _effect;
  204. return runner;
  205. }
  206. function stop(runner) {
  207. runner.effect.stop();
  208. }
  209. let shouldTrack = true;
  210. const trackStack = [];
  211. function pauseTracking() {
  212. trackStack.push(shouldTrack);
  213. shouldTrack = false;
  214. }
  215. function enableTracking() {
  216. trackStack.push(shouldTrack);
  217. shouldTrack = true;
  218. }
  219. function resetTracking() {
  220. const last = trackStack.pop();
  221. shouldTrack = last === undefined ? true : last;
  222. }
  223. function track(target, type, key) {
  224. if (!isTracking()) {
  225. return;
  226. }
  227. let depsMap = targetMap.get(target);
  228. if (!depsMap) {
  229. targetMap.set(target, (depsMap = new Map()));
  230. }
  231. let dep = depsMap.get(key);
  232. if (!dep) {
  233. depsMap.set(key, (dep = createDep()));
  234. }
  235. const eventInfo = (process.env.NODE_ENV !== 'production')
  236. ? { effect: activeEffect, target, type, key }
  237. : undefined;
  238. trackEffects(dep, eventInfo);
  239. }
  240. function isTracking() {
  241. return shouldTrack && activeEffect !== undefined;
  242. }
  243. function trackEffects(dep, debuggerEventExtraInfo) {
  244. let shouldTrack = false;
  245. if (effectTrackDepth <= maxMarkerBits) {
  246. if (!newTracked(dep)) {
  247. dep.n |= trackOpBit; // set newly tracked
  248. shouldTrack = !wasTracked(dep);
  249. }
  250. }
  251. else {
  252. // Full cleanup mode.
  253. shouldTrack = !dep.has(activeEffect);
  254. }
  255. if (shouldTrack) {
  256. dep.add(activeEffect);
  257. activeEffect.deps.push(dep);
  258. if ((process.env.NODE_ENV !== 'production') && activeEffect.onTrack) {
  259. activeEffect.onTrack(Object.assign({
  260. effect: activeEffect
  261. }, debuggerEventExtraInfo));
  262. }
  263. }
  264. }
  265. function trigger(target, type, key, newValue, oldValue, oldTarget) {
  266. const depsMap = targetMap.get(target);
  267. if (!depsMap) {
  268. // never been tracked
  269. return;
  270. }
  271. let deps = [];
  272. if (type === "clear" /* CLEAR */) {
  273. // collection being cleared
  274. // trigger all effects for target
  275. deps = [...depsMap.values()];
  276. }
  277. else if (key === 'length' && isArray(target)) {
  278. depsMap.forEach((dep, key) => {
  279. if (key === 'length' || key >= newValue) {
  280. deps.push(dep);
  281. }
  282. });
  283. }
  284. else {
  285. // schedule runs for SET | ADD | DELETE
  286. if (key !== void 0) {
  287. deps.push(depsMap.get(key));
  288. }
  289. // also run for iteration key on ADD | DELETE | Map.SET
  290. switch (type) {
  291. case "add" /* ADD */:
  292. if (!isArray(target)) {
  293. deps.push(depsMap.get(ITERATE_KEY));
  294. if (isMap(target)) {
  295. deps.push(depsMap.get(MAP_KEY_ITERATE_KEY));
  296. }
  297. }
  298. else if (isIntegerKey(key)) {
  299. // new index added to array -> length changes
  300. deps.push(depsMap.get('length'));
  301. }
  302. break;
  303. case "delete" /* DELETE */:
  304. if (!isArray(target)) {
  305. deps.push(depsMap.get(ITERATE_KEY));
  306. if (isMap(target)) {
  307. deps.push(depsMap.get(MAP_KEY_ITERATE_KEY));
  308. }
  309. }
  310. break;
  311. case "set" /* SET */:
  312. if (isMap(target)) {
  313. deps.push(depsMap.get(ITERATE_KEY));
  314. }
  315. break;
  316. }
  317. }
  318. const eventInfo = (process.env.NODE_ENV !== 'production')
  319. ? { target, type, key, newValue, oldValue, oldTarget }
  320. : undefined;
  321. if (deps.length === 1) {
  322. if (deps[0]) {
  323. if ((process.env.NODE_ENV !== 'production')) {
  324. triggerEffects(deps[0], eventInfo);
  325. }
  326. else {
  327. triggerEffects(deps[0]);
  328. }
  329. }
  330. }
  331. else {
  332. const effects = [];
  333. for (const dep of deps) {
  334. if (dep) {
  335. effects.push(...dep);
  336. }
  337. }
  338. if ((process.env.NODE_ENV !== 'production')) {
  339. triggerEffects(createDep(effects), eventInfo);
  340. }
  341. else {
  342. triggerEffects(createDep(effects));
  343. }
  344. }
  345. }
  346. function triggerEffects(dep, debuggerEventExtraInfo) {
  347. // spread into array for stabilization
  348. for (const effect of isArray(dep) ? dep : [...dep]) {
  349. if (effect !== activeEffect || effect.allowRecurse) {
  350. if ((process.env.NODE_ENV !== 'production') && effect.onTrigger) {
  351. effect.onTrigger(extend({ effect }, debuggerEventExtraInfo));
  352. }
  353. if (effect.scheduler) {
  354. effect.scheduler();
  355. }
  356. else {
  357. effect.run();
  358. }
  359. }
  360. }
  361. }
  362. const isNonTrackableKeys = /*#__PURE__*/ makeMap(`__proto__,__v_isRef,__isVue`);
  363. const builtInSymbols = new Set(Object.getOwnPropertyNames(Symbol)
  364. .map(key => Symbol[key])
  365. .filter(isSymbol));
  366. const get = /*#__PURE__*/ createGetter();
  367. const shallowGet = /*#__PURE__*/ createGetter(false, true);
  368. const readonlyGet = /*#__PURE__*/ createGetter(true);
  369. const shallowReadonlyGet = /*#__PURE__*/ createGetter(true, true);
  370. const arrayInstrumentations = /*#__PURE__*/ createArrayInstrumentations();
  371. function createArrayInstrumentations() {
  372. const instrumentations = {};
  373. ['includes', 'indexOf', 'lastIndexOf'].forEach(key => {
  374. instrumentations[key] = function (...args) {
  375. const arr = toRaw(this);
  376. for (let i = 0, l = this.length; i < l; i++) {
  377. track(arr, "get" /* GET */, i + '');
  378. }
  379. // we run the method using the original args first (which may be reactive)
  380. const res = arr[key](...args);
  381. if (res === -1 || res === false) {
  382. // if that didn't work, run it again using raw values.
  383. return arr[key](...args.map(toRaw));
  384. }
  385. else {
  386. return res;
  387. }
  388. };
  389. });
  390. ['push', 'pop', 'shift', 'unshift', 'splice'].forEach(key => {
  391. instrumentations[key] = function (...args) {
  392. pauseTracking();
  393. const res = toRaw(this)[key].apply(this, args);
  394. resetTracking();
  395. return res;
  396. };
  397. });
  398. return instrumentations;
  399. }
  400. function createGetter(isReadonly = false, shallow = false) {
  401. return function get(target, key, receiver) {
  402. if (key === "__v_isReactive" /* IS_REACTIVE */) {
  403. return !isReadonly;
  404. }
  405. else if (key === "__v_isReadonly" /* IS_READONLY */) {
  406. return isReadonly;
  407. }
  408. else if (key === "__v_raw" /* RAW */ &&
  409. receiver ===
  410. (isReadonly
  411. ? shallow
  412. ? shallowReadonlyMap
  413. : readonlyMap
  414. : shallow
  415. ? shallowReactiveMap
  416. : reactiveMap).get(target)) {
  417. return target;
  418. }
  419. const targetIsArray = isArray(target);
  420. if (!isReadonly && targetIsArray && hasOwn(arrayInstrumentations, key)) {
  421. return Reflect.get(arrayInstrumentations, key, receiver);
  422. }
  423. const res = Reflect.get(target, key, receiver);
  424. if (isSymbol(key) ? builtInSymbols.has(key) : isNonTrackableKeys(key)) {
  425. return res;
  426. }
  427. if (!isReadonly) {
  428. track(target, "get" /* GET */, key);
  429. }
  430. if (shallow) {
  431. return res;
  432. }
  433. if (isRef(res)) {
  434. // ref unwrapping - does not apply for Array + integer key.
  435. const shouldUnwrap = !targetIsArray || !isIntegerKey(key);
  436. return shouldUnwrap ? res.value : res;
  437. }
  438. if (isObject(res)) {
  439. // Convert returned value into a proxy as well. we do the isObject check
  440. // here to avoid invalid value warning. Also need to lazy access readonly
  441. // and reactive here to avoid circular dependency.
  442. return isReadonly ? readonly(res) : reactive(res);
  443. }
  444. return res;
  445. };
  446. }
  447. const set = /*#__PURE__*/ createSetter();
  448. const shallowSet = /*#__PURE__*/ createSetter(true);
  449. function createSetter(shallow = false) {
  450. return function set(target, key, value, receiver) {
  451. let oldValue = target[key];
  452. if (!shallow && !isReadonly(value)) {
  453. value = toRaw(value);
  454. oldValue = toRaw(oldValue);
  455. if (!isArray(target) && isRef(oldValue) && !isRef(value)) {
  456. oldValue.value = value;
  457. return true;
  458. }
  459. }
  460. const hadKey = isArray(target) && isIntegerKey(key)
  461. ? Number(key) < target.length
  462. : hasOwn(target, key);
  463. const result = Reflect.set(target, key, value, receiver);
  464. // don't trigger if target is something up in the prototype chain of original
  465. if (target === toRaw(receiver)) {
  466. if (!hadKey) {
  467. trigger(target, "add" /* ADD */, key, value);
  468. }
  469. else if (hasChanged(value, oldValue)) {
  470. trigger(target, "set" /* SET */, key, value, oldValue);
  471. }
  472. }
  473. return result;
  474. };
  475. }
  476. function deleteProperty(target, key) {
  477. const hadKey = hasOwn(target, key);
  478. const oldValue = target[key];
  479. const result = Reflect.deleteProperty(target, key);
  480. if (result && hadKey) {
  481. trigger(target, "delete" /* DELETE */, key, undefined, oldValue);
  482. }
  483. return result;
  484. }
  485. function has(target, key) {
  486. const result = Reflect.has(target, key);
  487. if (!isSymbol(key) || !builtInSymbols.has(key)) {
  488. track(target, "has" /* HAS */, key);
  489. }
  490. return result;
  491. }
  492. function ownKeys(target) {
  493. track(target, "iterate" /* ITERATE */, isArray(target) ? 'length' : ITERATE_KEY);
  494. return Reflect.ownKeys(target);
  495. }
  496. const mutableHandlers = {
  497. get,
  498. set,
  499. deleteProperty,
  500. has,
  501. ownKeys
  502. };
  503. const readonlyHandlers = {
  504. get: readonlyGet,
  505. set(target, key) {
  506. if ((process.env.NODE_ENV !== 'production')) {
  507. console.warn(`Set operation on key "${String(key)}" failed: target is readonly.`, target);
  508. }
  509. return true;
  510. },
  511. deleteProperty(target, key) {
  512. if ((process.env.NODE_ENV !== 'production')) {
  513. console.warn(`Delete operation on key "${String(key)}" failed: target is readonly.`, target);
  514. }
  515. return true;
  516. }
  517. };
  518. const shallowReactiveHandlers = /*#__PURE__*/ extend({}, mutableHandlers, {
  519. get: shallowGet,
  520. set: shallowSet
  521. });
  522. // Props handlers are special in the sense that it should not unwrap top-level
  523. // refs (in order to allow refs to be explicitly passed down), but should
  524. // retain the reactivity of the normal readonly object.
  525. const shallowReadonlyHandlers = /*#__PURE__*/ extend({}, readonlyHandlers, {
  526. get: shallowReadonlyGet
  527. });
  528. const toShallow = (value) => value;
  529. const getProto = (v) => Reflect.getPrototypeOf(v);
  530. function get$1(target, key, isReadonly = false, isShallow = false) {
  531. // #1772: readonly(reactive(Map)) should return readonly + reactive version
  532. // of the value
  533. target = target["__v_raw" /* RAW */];
  534. const rawTarget = toRaw(target);
  535. const rawKey = toRaw(key);
  536. if (key !== rawKey) {
  537. !isReadonly && track(rawTarget, "get" /* GET */, key);
  538. }
  539. !isReadonly && track(rawTarget, "get" /* GET */, rawKey);
  540. const { has } = getProto(rawTarget);
  541. const wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive;
  542. if (has.call(rawTarget, key)) {
  543. return wrap(target.get(key));
  544. }
  545. else if (has.call(rawTarget, rawKey)) {
  546. return wrap(target.get(rawKey));
  547. }
  548. else if (target !== rawTarget) {
  549. // #3602 readonly(reactive(Map))
  550. // ensure that the nested reactive `Map` can do tracking for itself
  551. target.get(key);
  552. }
  553. }
  554. function has$1(key, isReadonly = false) {
  555. const target = this["__v_raw" /* RAW */];
  556. const rawTarget = toRaw(target);
  557. const rawKey = toRaw(key);
  558. if (key !== rawKey) {
  559. !isReadonly && track(rawTarget, "has" /* HAS */, key);
  560. }
  561. !isReadonly && track(rawTarget, "has" /* HAS */, rawKey);
  562. return key === rawKey
  563. ? target.has(key)
  564. : target.has(key) || target.has(rawKey);
  565. }
  566. function size(target, isReadonly = false) {
  567. target = target["__v_raw" /* RAW */];
  568. !isReadonly && track(toRaw(target), "iterate" /* ITERATE */, ITERATE_KEY);
  569. return Reflect.get(target, 'size', target);
  570. }
  571. function add(value) {
  572. value = toRaw(value);
  573. const target = toRaw(this);
  574. const proto = getProto(target);
  575. const hadKey = proto.has.call(target, value);
  576. if (!hadKey) {
  577. target.add(value);
  578. trigger(target, "add" /* ADD */, value, value);
  579. }
  580. return this;
  581. }
  582. function set$1(key, value) {
  583. value = toRaw(value);
  584. const target = toRaw(this);
  585. const { has, get } = getProto(target);
  586. let hadKey = has.call(target, key);
  587. if (!hadKey) {
  588. key = toRaw(key);
  589. hadKey = has.call(target, key);
  590. }
  591. else if ((process.env.NODE_ENV !== 'production')) {
  592. checkIdentityKeys(target, has, key);
  593. }
  594. const oldValue = get.call(target, key);
  595. target.set(key, value);
  596. if (!hadKey) {
  597. trigger(target, "add" /* ADD */, key, value);
  598. }
  599. else if (hasChanged(value, oldValue)) {
  600. trigger(target, "set" /* SET */, key, value, oldValue);
  601. }
  602. return this;
  603. }
  604. function deleteEntry(key) {
  605. const target = toRaw(this);
  606. const { has, get } = getProto(target);
  607. let hadKey = has.call(target, key);
  608. if (!hadKey) {
  609. key = toRaw(key);
  610. hadKey = has.call(target, key);
  611. }
  612. else if ((process.env.NODE_ENV !== 'production')) {
  613. checkIdentityKeys(target, has, key);
  614. }
  615. const oldValue = get ? get.call(target, key) : undefined;
  616. // forward the operation before queueing reactions
  617. const result = target.delete(key);
  618. if (hadKey) {
  619. trigger(target, "delete" /* DELETE */, key, undefined, oldValue);
  620. }
  621. return result;
  622. }
  623. function clear() {
  624. const target = toRaw(this);
  625. const hadItems = target.size !== 0;
  626. const oldTarget = (process.env.NODE_ENV !== 'production')
  627. ? isMap(target)
  628. ? new Map(target)
  629. : new Set(target)
  630. : undefined;
  631. // forward the operation before queueing reactions
  632. const result = target.clear();
  633. if (hadItems) {
  634. trigger(target, "clear" /* CLEAR */, undefined, undefined, oldTarget);
  635. }
  636. return result;
  637. }
  638. function createForEach(isReadonly, isShallow) {
  639. return function forEach(callback, thisArg) {
  640. const observed = this;
  641. const target = observed["__v_raw" /* RAW */];
  642. const rawTarget = toRaw(target);
  643. const wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive;
  644. !isReadonly && track(rawTarget, "iterate" /* ITERATE */, ITERATE_KEY);
  645. return target.forEach((value, key) => {
  646. // important: make sure the callback is
  647. // 1. invoked with the reactive map as `this` and 3rd arg
  648. // 2. the value received should be a corresponding reactive/readonly.
  649. return callback.call(thisArg, wrap(value), wrap(key), observed);
  650. });
  651. };
  652. }
  653. function createIterableMethod(method, isReadonly, isShallow) {
  654. return function (...args) {
  655. const target = this["__v_raw" /* RAW */];
  656. const rawTarget = toRaw(target);
  657. const targetIsMap = isMap(rawTarget);
  658. const isPair = method === 'entries' || (method === Symbol.iterator && targetIsMap);
  659. const isKeyOnly = method === 'keys' && targetIsMap;
  660. const innerIterator = target[method](...args);
  661. const wrap = isShallow ? toShallow : isReadonly ? toReadonly : toReactive;
  662. !isReadonly &&
  663. track(rawTarget, "iterate" /* ITERATE */, isKeyOnly ? MAP_KEY_ITERATE_KEY : ITERATE_KEY);
  664. // return a wrapped iterator which returns observed versions of the
  665. // values emitted from the real iterator
  666. return {
  667. // iterator protocol
  668. next() {
  669. const { value, done } = innerIterator.next();
  670. return done
  671. ? { value, done }
  672. : {
  673. value: isPair ? [wrap(value[0]), wrap(value[1])] : wrap(value),
  674. done
  675. };
  676. },
  677. // iterable protocol
  678. [Symbol.iterator]() {
  679. return this;
  680. }
  681. };
  682. };
  683. }
  684. function createReadonlyMethod(type) {
  685. return function (...args) {
  686. if ((process.env.NODE_ENV !== 'production')) {
  687. const key = args[0] ? `on key "${args[0]}" ` : ``;
  688. console.warn(`${capitalize(type)} operation ${key}failed: target is readonly.`, toRaw(this));
  689. }
  690. return type === "delete" /* DELETE */ ? false : this;
  691. };
  692. }
  693. function createInstrumentations() {
  694. const mutableInstrumentations = {
  695. get(key) {
  696. return get$1(this, key);
  697. },
  698. get size() {
  699. return size(this);
  700. },
  701. has: has$1,
  702. add,
  703. set: set$1,
  704. delete: deleteEntry,
  705. clear,
  706. forEach: createForEach(false, false)
  707. };
  708. const shallowInstrumentations = {
  709. get(key) {
  710. return get$1(this, key, false, true);
  711. },
  712. get size() {
  713. return size(this);
  714. },
  715. has: has$1,
  716. add,
  717. set: set$1,
  718. delete: deleteEntry,
  719. clear,
  720. forEach: createForEach(false, true)
  721. };
  722. const readonlyInstrumentations = {
  723. get(key) {
  724. return get$1(this, key, true);
  725. },
  726. get size() {
  727. return size(this, true);
  728. },
  729. has(key) {
  730. return has$1.call(this, key, true);
  731. },
  732. add: createReadonlyMethod("add" /* ADD */),
  733. set: createReadonlyMethod("set" /* SET */),
  734. delete: createReadonlyMethod("delete" /* DELETE */),
  735. clear: createReadonlyMethod("clear" /* CLEAR */),
  736. forEach: createForEach(true, false)
  737. };
  738. const shallowReadonlyInstrumentations = {
  739. get(key) {
  740. return get$1(this, key, true, true);
  741. },
  742. get size() {
  743. return size(this, true);
  744. },
  745. has(key) {
  746. return has$1.call(this, key, true);
  747. },
  748. add: createReadonlyMethod("add" /* ADD */),
  749. set: createReadonlyMethod("set" /* SET */),
  750. delete: createReadonlyMethod("delete" /* DELETE */),
  751. clear: createReadonlyMethod("clear" /* CLEAR */),
  752. forEach: createForEach(true, true)
  753. };
  754. const iteratorMethods = ['keys', 'values', 'entries', Symbol.iterator];
  755. iteratorMethods.forEach(method => {
  756. mutableInstrumentations[method] = createIterableMethod(method, false, false);
  757. readonlyInstrumentations[method] = createIterableMethod(method, true, false);
  758. shallowInstrumentations[method] = createIterableMethod(method, false, true);
  759. shallowReadonlyInstrumentations[method] = createIterableMethod(method, true, true);
  760. });
  761. return [
  762. mutableInstrumentations,
  763. readonlyInstrumentations,
  764. shallowInstrumentations,
  765. shallowReadonlyInstrumentations
  766. ];
  767. }
  768. const [mutableInstrumentations, readonlyInstrumentations, shallowInstrumentations, shallowReadonlyInstrumentations] = /* #__PURE__*/ createInstrumentations();
  769. function createInstrumentationGetter(isReadonly, shallow) {
  770. const instrumentations = shallow
  771. ? isReadonly
  772. ? shallowReadonlyInstrumentations
  773. : shallowInstrumentations
  774. : isReadonly
  775. ? readonlyInstrumentations
  776. : mutableInstrumentations;
  777. return (target, key, receiver) => {
  778. if (key === "__v_isReactive" /* IS_REACTIVE */) {
  779. return !isReadonly;
  780. }
  781. else if (key === "__v_isReadonly" /* IS_READONLY */) {
  782. return isReadonly;
  783. }
  784. else if (key === "__v_raw" /* RAW */) {
  785. return target;
  786. }
  787. return Reflect.get(hasOwn(instrumentations, key) && key in target
  788. ? instrumentations
  789. : target, key, receiver);
  790. };
  791. }
  792. const mutableCollectionHandlers = {
  793. get: /*#__PURE__*/ createInstrumentationGetter(false, false)
  794. };
  795. const shallowCollectionHandlers = {
  796. get: /*#__PURE__*/ createInstrumentationGetter(false, true)
  797. };
  798. const readonlyCollectionHandlers = {
  799. get: /*#__PURE__*/ createInstrumentationGetter(true, false)
  800. };
  801. const shallowReadonlyCollectionHandlers = {
  802. get: /*#__PURE__*/ createInstrumentationGetter(true, true)
  803. };
  804. function checkIdentityKeys(target, has, key) {
  805. const rawKey = toRaw(key);
  806. if (rawKey !== key && has.call(target, rawKey)) {
  807. const type = toRawType(target);
  808. console.warn(`Reactive ${type} contains both the raw and reactive ` +
  809. `versions of the same object${type === `Map` ? ` as keys` : ``}, ` +
  810. `which can lead to inconsistencies. ` +
  811. `Avoid differentiating between the raw and reactive versions ` +
  812. `of an object and only use the reactive version if possible.`);
  813. }
  814. }
  815. const reactiveMap = new WeakMap();
  816. const shallowReactiveMap = new WeakMap();
  817. const readonlyMap = new WeakMap();
  818. const shallowReadonlyMap = new WeakMap();
  819. function targetTypeMap(rawType) {
  820. switch (rawType) {
  821. case 'Object':
  822. case 'Array':
  823. return 1 /* COMMON */;
  824. case 'Map':
  825. case 'Set':
  826. case 'WeakMap':
  827. case 'WeakSet':
  828. return 2 /* COLLECTION */;
  829. default:
  830. return 0 /* INVALID */;
  831. }
  832. }
  833. function getTargetType(value) {
  834. return value["__v_skip" /* SKIP */] || !Object.isExtensible(value)
  835. ? 0 /* INVALID */
  836. : targetTypeMap(toRawType(value));
  837. }
  838. function reactive(target) {
  839. // if trying to observe a readonly proxy, return the readonly version.
  840. if (target && target["__v_isReadonly" /* IS_READONLY */]) {
  841. return target;
  842. }
  843. return createReactiveObject(target, false, mutableHandlers, mutableCollectionHandlers, reactiveMap);
  844. }
  845. /**
  846. * Return a shallowly-reactive copy of the original object, where only the root
  847. * level properties are reactive. It also does not auto-unwrap refs (even at the
  848. * root level).
  849. */
  850. function shallowReactive(target) {
  851. return createReactiveObject(target, false, shallowReactiveHandlers, shallowCollectionHandlers, shallowReactiveMap);
  852. }
  853. /**
  854. * Creates a readonly copy of the original object. Note the returned copy is not
  855. * made reactive, but `readonly` can be called on an already reactive object.
  856. */
  857. function readonly(target) {
  858. return createReactiveObject(target, true, readonlyHandlers, readonlyCollectionHandlers, readonlyMap);
  859. }
  860. /**
  861. * Returns a reactive-copy of the original object, where only the root level
  862. * properties are readonly, and does NOT unwrap refs nor recursively convert
  863. * returned properties.
  864. * This is used for creating the props proxy object for stateful components.
  865. */
  866. function shallowReadonly(target) {
  867. return createReactiveObject(target, true, shallowReadonlyHandlers, shallowReadonlyCollectionHandlers, shallowReadonlyMap);
  868. }
  869. function createReactiveObject(target, isReadonly, baseHandlers, collectionHandlers, proxyMap) {
  870. if (!isObject(target)) {
  871. if ((process.env.NODE_ENV !== 'production')) {
  872. console.warn(`value cannot be made reactive: ${String(target)}`);
  873. }
  874. return target;
  875. }
  876. // target is already a Proxy, return it.
  877. // exception: calling readonly() on a reactive object
  878. if (target["__v_raw" /* RAW */] &&
  879. !(isReadonly && target["__v_isReactive" /* IS_REACTIVE */])) {
  880. return target;
  881. }
  882. // target already has corresponding Proxy
  883. const existingProxy = proxyMap.get(target);
  884. if (existingProxy) {
  885. return existingProxy;
  886. }
  887. // only a whitelist of value types can be observed.
  888. const targetType = getTargetType(target);
  889. if (targetType === 0 /* INVALID */) {
  890. return target;
  891. }
  892. const proxy = new Proxy(target, targetType === 2 /* COLLECTION */ ? collectionHandlers : baseHandlers);
  893. proxyMap.set(target, proxy);
  894. return proxy;
  895. }
  896. function isReactive(value) {
  897. if (isReadonly(value)) {
  898. return isReactive(value["__v_raw" /* RAW */]);
  899. }
  900. return !!(value && value["__v_isReactive" /* IS_REACTIVE */]);
  901. }
  902. function isReadonly(value) {
  903. return !!(value && value["__v_isReadonly" /* IS_READONLY */]);
  904. }
  905. function isProxy(value) {
  906. return isReactive(value) || isReadonly(value);
  907. }
  908. function toRaw(observed) {
  909. const raw = observed && observed["__v_raw" /* RAW */];
  910. return raw ? toRaw(raw) : observed;
  911. }
  912. function markRaw(value) {
  913. def(value, "__v_skip" /* SKIP */, true);
  914. return value;
  915. }
  916. const toReactive = (value) => isObject(value) ? reactive(value) : value;
  917. const toReadonly = (value) => isObject(value) ? readonly(value) : value;
  918. function trackRefValue(ref) {
  919. if (isTracking()) {
  920. ref = toRaw(ref);
  921. if (!ref.dep) {
  922. ref.dep = createDep();
  923. }
  924. if ((process.env.NODE_ENV !== 'production')) {
  925. trackEffects(ref.dep, {
  926. target: ref,
  927. type: "get" /* GET */,
  928. key: 'value'
  929. });
  930. }
  931. else {
  932. trackEffects(ref.dep);
  933. }
  934. }
  935. }
  936. function triggerRefValue(ref, newVal) {
  937. ref = toRaw(ref);
  938. if (ref.dep) {
  939. if ((process.env.NODE_ENV !== 'production')) {
  940. triggerEffects(ref.dep, {
  941. target: ref,
  942. type: "set" /* SET */,
  943. key: 'value',
  944. newValue: newVal
  945. });
  946. }
  947. else {
  948. triggerEffects(ref.dep);
  949. }
  950. }
  951. }
  952. function isRef(r) {
  953. return Boolean(r && r.__v_isRef === true);
  954. }
  955. function ref(value) {
  956. return createRef(value, false);
  957. }
  958. function shallowRef(value) {
  959. return createRef(value, true);
  960. }
  961. function createRef(rawValue, shallow) {
  962. if (isRef(rawValue)) {
  963. return rawValue;
  964. }
  965. return new RefImpl(rawValue, shallow);
  966. }
  967. class RefImpl {
  968. constructor(value, _shallow) {
  969. this._shallow = _shallow;
  970. this.dep = undefined;
  971. this.__v_isRef = true;
  972. this._rawValue = _shallow ? value : toRaw(value);
  973. this._value = _shallow ? value : toReactive(value);
  974. }
  975. get value() {
  976. trackRefValue(this);
  977. return this._value;
  978. }
  979. set value(newVal) {
  980. newVal = this._shallow ? newVal : toRaw(newVal);
  981. if (hasChanged(newVal, this._rawValue)) {
  982. this._rawValue = newVal;
  983. this._value = this._shallow ? newVal : toReactive(newVal);
  984. triggerRefValue(this, newVal);
  985. }
  986. }
  987. }
  988. function triggerRef(ref) {
  989. triggerRefValue(ref, (process.env.NODE_ENV !== 'production') ? ref.value : void 0);
  990. }
  991. function unref(ref) {
  992. return isRef(ref) ? ref.value : ref;
  993. }
  994. const shallowUnwrapHandlers = {
  995. get: (target, key, receiver) => unref(Reflect.get(target, key, receiver)),
  996. set: (target, key, value, receiver) => {
  997. const oldValue = target[key];
  998. if (isRef(oldValue) && !isRef(value)) {
  999. oldValue.value = value;
  1000. return true;
  1001. }
  1002. else {
  1003. return Reflect.set(target, key, value, receiver);
  1004. }
  1005. }
  1006. };
  1007. function proxyRefs(objectWithRefs) {
  1008. return isReactive(objectWithRefs)
  1009. ? objectWithRefs
  1010. : new Proxy(objectWithRefs, shallowUnwrapHandlers);
  1011. }
  1012. class CustomRefImpl {
  1013. constructor(factory) {
  1014. this.dep = undefined;
  1015. this.__v_isRef = true;
  1016. const { get, set } = factory(() => trackRefValue(this), () => triggerRefValue(this));
  1017. this._get = get;
  1018. this._set = set;
  1019. }
  1020. get value() {
  1021. return this._get();
  1022. }
  1023. set value(newVal) {
  1024. this._set(newVal);
  1025. }
  1026. }
  1027. function customRef(factory) {
  1028. return new CustomRefImpl(factory);
  1029. }
  1030. function toRefs(object) {
  1031. if ((process.env.NODE_ENV !== 'production') && !isProxy(object)) {
  1032. console.warn(`toRefs() expects a reactive object but received a plain one.`);
  1033. }
  1034. const ret = isArray(object) ? new Array(object.length) : {};
  1035. for (const key in object) {
  1036. ret[key] = toRef(object, key);
  1037. }
  1038. return ret;
  1039. }
  1040. class ObjectRefImpl {
  1041. constructor(_object, _key, _defaultValue) {
  1042. this._object = _object;
  1043. this._key = _key;
  1044. this._defaultValue = _defaultValue;
  1045. this.__v_isRef = true;
  1046. }
  1047. get value() {
  1048. const val = this._object[this._key];
  1049. return val === undefined ? this._defaultValue : val;
  1050. }
  1051. set value(newVal) {
  1052. this._object[this._key] = newVal;
  1053. }
  1054. }
  1055. function toRef(object, key, defaultValue) {
  1056. const val = object[key];
  1057. return isRef(val)
  1058. ? val
  1059. : new ObjectRefImpl(object, key, defaultValue);
  1060. }
  1061. class ComputedRefImpl {
  1062. constructor(getter, _setter, isReadonly) {
  1063. this._setter = _setter;
  1064. this.dep = undefined;
  1065. this._dirty = true;
  1066. this.__v_isRef = true;
  1067. this.effect = new ReactiveEffect(getter, () => {
  1068. if (!this._dirty) {
  1069. this._dirty = true;
  1070. triggerRefValue(this);
  1071. }
  1072. });
  1073. this["__v_isReadonly" /* IS_READONLY */] = isReadonly;
  1074. }
  1075. get value() {
  1076. // the computed ref may get wrapped by other proxies e.g. readonly() #3376
  1077. const self = toRaw(this);
  1078. trackRefValue(self);
  1079. if (self._dirty) {
  1080. self._dirty = false;
  1081. self._value = self.effect.run();
  1082. }
  1083. return self._value;
  1084. }
  1085. set value(newValue) {
  1086. this._setter(newValue);
  1087. }
  1088. }
  1089. function computed(getterOrOptions, debugOptions) {
  1090. let getter;
  1091. let setter;
  1092. const onlyGetter = isFunction(getterOrOptions);
  1093. if (onlyGetter) {
  1094. getter = getterOrOptions;
  1095. setter = (process.env.NODE_ENV !== 'production')
  1096. ? () => {
  1097. console.warn('Write operation failed: computed value is readonly');
  1098. }
  1099. : NOOP;
  1100. }
  1101. else {
  1102. getter = getterOrOptions.get;
  1103. setter = getterOrOptions.set;
  1104. }
  1105. const cRef = new ComputedRefImpl(getter, setter, onlyGetter || !setter);
  1106. if ((process.env.NODE_ENV !== 'production') && debugOptions) {
  1107. cRef.effect.onTrack = debugOptions.onTrack;
  1108. cRef.effect.onTrigger = debugOptions.onTrigger;
  1109. }
  1110. return cRef;
  1111. }
  1112. var _a;
  1113. const tick = Promise.resolve();
  1114. const queue = [];
  1115. let queued = false;
  1116. const scheduler = (fn) => {
  1117. queue.push(fn);
  1118. if (!queued) {
  1119. queued = true;
  1120. tick.then(flush);
  1121. }
  1122. };
  1123. const flush = () => {
  1124. for (let i = 0; i < queue.length; i++) {
  1125. queue[i]();
  1126. }
  1127. queue.length = 0;
  1128. queued = false;
  1129. };
  1130. class DeferredComputedRefImpl {
  1131. constructor(getter) {
  1132. this.dep = undefined;
  1133. this._dirty = true;
  1134. this.__v_isRef = true;
  1135. this[_a] = true;
  1136. let compareTarget;
  1137. let hasCompareTarget = false;
  1138. let scheduled = false;
  1139. this.effect = new ReactiveEffect(getter, (computedTrigger) => {
  1140. if (this.dep) {
  1141. if (computedTrigger) {
  1142. compareTarget = this._value;
  1143. hasCompareTarget = true;
  1144. }
  1145. else if (!scheduled) {
  1146. const valueToCompare = hasCompareTarget ? compareTarget : this._value;
  1147. scheduled = true;
  1148. hasCompareTarget = false;
  1149. scheduler(() => {
  1150. if (this.effect.active && this._get() !== valueToCompare) {
  1151. triggerRefValue(this);
  1152. }
  1153. scheduled = false;
  1154. });
  1155. }
  1156. // chained upstream computeds are notified synchronously to ensure
  1157. // value invalidation in case of sync access; normal effects are
  1158. // deferred to be triggered in scheduler.
  1159. for (const e of this.dep) {
  1160. if (e.computed) {
  1161. e.scheduler(true /* computedTrigger */);
  1162. }
  1163. }
  1164. }
  1165. this._dirty = true;
  1166. });
  1167. this.effect.computed = true;
  1168. }
  1169. _get() {
  1170. if (this._dirty) {
  1171. this._dirty = false;
  1172. return (this._value = this.effect.run());
  1173. }
  1174. return this._value;
  1175. }
  1176. get value() {
  1177. trackRefValue(this);
  1178. // the computed ref may get wrapped by other proxies e.g. readonly() #3376
  1179. return toRaw(this)._get();
  1180. }
  1181. }
  1182. _a = "__v_isReadonly" /* IS_READONLY */;
  1183. function deferredComputed(getter) {
  1184. return new DeferredComputedRefImpl(getter);
  1185. }
  1186. export { EffectScope, ITERATE_KEY, ReactiveEffect, computed, customRef, deferredComputed, effect, effectScope, enableTracking, getCurrentScope, isProxy, isReactive, isReadonly, isRef, markRaw, onScopeDispose, pauseTracking, proxyRefs, reactive, readonly, ref, resetTracking, shallowReactive, shallowReadonly, shallowRef, stop, toRaw, toRef, toRefs, track, trigger, triggerRef, unref };