reactivity.global.js 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946
  1. var VueReactivity = (function (exports) {
  2. 'use strict';
  3. /**
  4. * Make a map and return a function for checking if a key
  5. * is in that map.
  6. * IMPORTANT: all calls of this function must be prefixed with
  7. * \/\*#\_\_PURE\_\_\*\/
  8. * So that rollup can tree-shake them if necessary.
  9. */
  10. function makeMap(str, expectsLowerCase) {
  11. const map = Object.create(null);
  12. const list = str.split(',');
  13. for (let i = 0; i < list.length; i++) {
  14. map[list[i]] = true;
  15. }
  16. return expectsLowerCase ? val => !!map[val.toLowerCase()] : val => !!map[val];
  17. }
  18. const EMPTY_OBJ = Object.freeze({})
  19. ;
  20. Object.freeze([]) ;
  21. const extend = Object.assign;
  22. const hasOwnProperty = Object.prototype.hasOwnProperty;
  23. const hasOwn = (val, key) => hasOwnProperty.call(val, key);
  24. const isArray = Array.isArray;
  25. const isMap = (val) => toTypeString(val) === '[object Map]';
  26. const isFunction = (val) => typeof val === 'function';
  27. const isString = (val) => typeof val === 'string';
  28. const isSymbol = (val) => typeof val === 'symbol';
  29. const isObject = (val) => val !== null && typeof val === 'object';
  30. const objectToString = Object.prototype.toString;
  31. const toTypeString = (value) => objectToString.call(value);
  32. const toRawType = (value) => {
  33. // extract "RawType" from strings like "[object RawType]"
  34. return toTypeString(value).slice(8, -1);
  35. };
  36. const isIntegerKey = (key) => isString(key) &&
  37. key !== 'NaN' &&
  38. key[0] !== '-' &&
  39. '' + parseInt(key, 10) === key;
  40. const cacheStringFunction = (fn) => {
  41. const cache = Object.create(null);
  42. return ((str) => {
  43. const hit = cache[str];
  44. return hit || (cache[str] = fn(str));
  45. });
  46. };
  47. /**
  48. * @private
  49. */
  50. const capitalize = cacheStringFunction((str) => str.charAt(0).toUpperCase() + str.slice(1));
  51. // compare whether a value has changed, accounting for NaN.
  52. const hasChanged = (value, oldValue) => value !== oldValue && (value === value || oldValue === oldValue);
  53. const def = (obj, key, value) => {
  54. Object.defineProperty(obj, key, {
  55. configurable: true,
  56. enumerable: false,
  57. value
  58. });
  59. };
  60. const targetMap = new WeakMap();
  61. const effectStack = [];
  62. let activeEffect;
  63. const ITERATE_KEY = Symbol('iterate' );
  64. const MAP_KEY_ITERATE_KEY = Symbol('Map key iterate' );
  65. function isEffect(fn) {
  66. return fn && fn._isEffect === true;
  67. }
  68. function effect(fn, options = EMPTY_OBJ) {
  69. if (isEffect(fn)) {
  70. fn = fn.raw;
  71. }
  72. const effect = createReactiveEffect(fn, options);
  73. if (!options.lazy) {
  74. effect();
  75. }
  76. return effect;
  77. }
  78. function stop(effect) {
  79. if (effect.active) {
  80. cleanup(effect);
  81. if (effect.options.onStop) {
  82. effect.options.onStop();
  83. }
  84. effect.active = false;
  85. }
  86. }
  87. let uid = 0;
  88. function createReactiveEffect(fn, options) {
  89. const effect = function reactiveEffect() {
  90. if (!effect.active) {
  91. return options.scheduler ? undefined : fn();
  92. }
  93. if (!effectStack.includes(effect)) {
  94. cleanup(effect);
  95. try {
  96. enableTracking();
  97. effectStack.push(effect);
  98. activeEffect = effect;
  99. return fn();
  100. }
  101. finally {
  102. effectStack.pop();
  103. resetTracking();
  104. activeEffect = effectStack[effectStack.length - 1];
  105. }
  106. }
  107. };
  108. effect.id = uid++;
  109. effect.allowRecurse = !!options.allowRecurse;
  110. effect._isEffect = true;
  111. effect.active = true;
  112. effect.raw = fn;
  113. effect.deps = [];
  114. effect.options = options;
  115. return effect;
  116. }
  117. function cleanup(effect) {
  118. const { deps } = effect;
  119. if (deps.length) {
  120. for (let i = 0; i < deps.length; i++) {
  121. deps[i].delete(effect);
  122. }
  123. deps.length = 0;
  124. }
  125. }
  126. let shouldTrack = true;
  127. const trackStack = [];
  128. function pauseTracking() {
  129. trackStack.push(shouldTrack);
  130. shouldTrack = false;
  131. }
  132. function enableTracking() {
  133. trackStack.push(shouldTrack);
  134. shouldTrack = true;
  135. }
  136. function resetTracking() {
  137. const last = trackStack.pop();
  138. shouldTrack = last === undefined ? true : last;
  139. }
  140. function track(target, type, key) {
  141. if (!shouldTrack || activeEffect === undefined) {
  142. return;
  143. }
  144. let depsMap = targetMap.get(target);
  145. if (!depsMap) {
  146. targetMap.set(target, (depsMap = new Map()));
  147. }
  148. let dep = depsMap.get(key);
  149. if (!dep) {
  150. depsMap.set(key, (dep = new Set()));
  151. }
  152. if (!dep.has(activeEffect)) {
  153. dep.add(activeEffect);
  154. activeEffect.deps.push(dep);
  155. if (activeEffect.options.onTrack) {
  156. activeEffect.options.onTrack({
  157. effect: activeEffect,
  158. target,
  159. type,
  160. key
  161. });
  162. }
  163. }
  164. }
  165. function trigger(target, type, key, newValue, oldValue, oldTarget) {
  166. const depsMap = targetMap.get(target);
  167. if (!depsMap) {
  168. // never been tracked
  169. return;
  170. }
  171. const effects = new Set();
  172. const add = (effectsToAdd) => {
  173. if (effectsToAdd) {
  174. effectsToAdd.forEach(effect => {
  175. if (effect !== activeEffect || effect.allowRecurse) {
  176. effects.add(effect);
  177. }
  178. });
  179. }
  180. };
  181. if (type === "clear" /* CLEAR */) {
  182. // collection being cleared
  183. // trigger all effects for target
  184. depsMap.forEach(add);
  185. }
  186. else if (key === 'length' && isArray(target)) {
  187. depsMap.forEach((dep, key) => {
  188. if (key === 'length' || key >= newValue) {
  189. add(dep);
  190. }
  191. });
  192. }
  193. else {
  194. // schedule runs for SET | ADD | DELETE
  195. if (key !== void 0) {
  196. add(depsMap.get(key));
  197. }
  198. // also run for iteration key on ADD | DELETE | Map.SET
  199. switch (type) {
  200. case "add" /* ADD */:
  201. if (!isArray(target)) {
  202. add(depsMap.get(ITERATE_KEY));
  203. if (isMap(target)) {
  204. add(depsMap.get(MAP_KEY_ITERATE_KEY));
  205. }
  206. }
  207. else if (isIntegerKey(key)) {
  208. // new index added to array -> length changes
  209. add(depsMap.get('length'));
  210. }
  211. break;
  212. case "delete" /* DELETE */:
  213. if (!isArray(target)) {
  214. add(depsMap.get(ITERATE_KEY));
  215. if (isMap(target)) {
  216. add(depsMap.get(MAP_KEY_ITERATE_KEY));
  217. }
  218. }
  219. break;
  220. case "set" /* SET */:
  221. if (isMap(target)) {
  222. add(depsMap.get(ITERATE_KEY));
  223. }
  224. break;
  225. }
  226. }
  227. const run = (effect) => {
  228. if (effect.options.onTrigger) {
  229. effect.options.onTrigger({
  230. effect,
  231. target,
  232. key,
  233. type,
  234. newValue,
  235. oldValue,
  236. oldTarget
  237. });
  238. }
  239. if (effect.options.scheduler) {
  240. effect.options.scheduler(effect);
  241. }
  242. else {
  243. effect();
  244. }
  245. };
  246. effects.forEach(run);
  247. }
  248. const isNonTrackableKeys = /*#__PURE__*/ makeMap(`__proto__,__v_isRef,__isVue`);
  249. const builtInSymbols = new Set(Object.getOwnPropertyNames(Symbol)
  250. .map(key => Symbol[key])
  251. .filter(isSymbol));
  252. const get = /*#__PURE__*/ createGetter();
  253. const shallowGet = /*#__PURE__*/ createGetter(false, true);
  254. const readonlyGet = /*#__PURE__*/ createGetter(true);
  255. const shallowReadonlyGet = /*#__PURE__*/ createGetter(true, true);
  256. const arrayInstrumentations = {};
  257. ['includes', 'indexOf', 'lastIndexOf'].forEach(key => {
  258. const method = Array.prototype[key];
  259. arrayInstrumentations[key] = function (...args) {
  260. const arr = toRaw(this);
  261. for (let i = 0, l = this.length; i < l; i++) {
  262. track(arr, "get" /* GET */, i + '');
  263. }
  264. // we run the method using the original args first (which may be reactive)
  265. const res = method.apply(arr, args);
  266. if (res === -1 || res === false) {
  267. // if that didn't work, run it again using raw values.
  268. return method.apply(arr, args.map(toRaw));
  269. }
  270. else {
  271. return res;
  272. }
  273. };
  274. });
  275. ['push', 'pop', 'shift', 'unshift', 'splice'].forEach(key => {
  276. const method = Array.prototype[key];
  277. arrayInstrumentations[key] = function (...args) {
  278. pauseTracking();
  279. const res = method.apply(this, args);
  280. resetTracking();
  281. return res;
  282. };
  283. });
  284. function createGetter(isReadonly = false, shallow = false) {
  285. return function get(target, key, receiver) {
  286. if (key === "__v_isReactive" /* IS_REACTIVE */) {
  287. return !isReadonly;
  288. }
  289. else if (key === "__v_isReadonly" /* IS_READONLY */) {
  290. return isReadonly;
  291. }
  292. else if (key === "__v_raw" /* RAW */ &&
  293. receiver === (isReadonly ? readonlyMap : reactiveMap).get(target)) {
  294. return target;
  295. }
  296. const targetIsArray = isArray(target);
  297. if (!isReadonly && targetIsArray && hasOwn(arrayInstrumentations, key)) {
  298. return Reflect.get(arrayInstrumentations, key, receiver);
  299. }
  300. const res = Reflect.get(target, key, receiver);
  301. if (isSymbol(key)
  302. ? builtInSymbols.has(key)
  303. : isNonTrackableKeys(key)) {
  304. return res;
  305. }
  306. if (!isReadonly) {
  307. track(target, "get" /* GET */, key);
  308. }
  309. if (shallow) {
  310. return res;
  311. }
  312. if (isRef(res)) {
  313. // ref unwrapping - does not apply for Array + integer key.
  314. const shouldUnwrap = !targetIsArray || !isIntegerKey(key);
  315. return shouldUnwrap ? res.value : res;
  316. }
  317. if (isObject(res)) {
  318. // Convert returned value into a proxy as well. we do the isObject check
  319. // here to avoid invalid value warning. Also need to lazy access readonly
  320. // and reactive here to avoid circular dependency.
  321. return isReadonly ? readonly(res) : reactive(res);
  322. }
  323. return res;
  324. };
  325. }
  326. const set = /*#__PURE__*/ createSetter();
  327. const shallowSet = /*#__PURE__*/ createSetter(true);
  328. function createSetter(shallow = false) {
  329. return function set(target, key, value, receiver) {
  330. const oldValue = target[key];
  331. if (!shallow) {
  332. value = toRaw(value);
  333. if (!isArray(target) && isRef(oldValue) && !isRef(value)) {
  334. oldValue.value = value;
  335. return true;
  336. }
  337. }
  338. const hadKey = isArray(target) && isIntegerKey(key)
  339. ? Number(key) < target.length
  340. : hasOwn(target, key);
  341. const result = Reflect.set(target, key, value, receiver);
  342. // don't trigger if target is something up in the prototype chain of original
  343. if (target === toRaw(receiver)) {
  344. if (!hadKey) {
  345. trigger(target, "add" /* ADD */, key, value);
  346. }
  347. else if (hasChanged(value, oldValue)) {
  348. trigger(target, "set" /* SET */, key, value, oldValue);
  349. }
  350. }
  351. return result;
  352. };
  353. }
  354. function deleteProperty(target, key) {
  355. const hadKey = hasOwn(target, key);
  356. const oldValue = target[key];
  357. const result = Reflect.deleteProperty(target, key);
  358. if (result && hadKey) {
  359. trigger(target, "delete" /* DELETE */, key, undefined, oldValue);
  360. }
  361. return result;
  362. }
  363. function has(target, key) {
  364. const result = Reflect.has(target, key);
  365. if (!isSymbol(key) || !builtInSymbols.has(key)) {
  366. track(target, "has" /* HAS */, key);
  367. }
  368. return result;
  369. }
  370. function ownKeys(target) {
  371. track(target, "iterate" /* ITERATE */, isArray(target) ? 'length' : ITERATE_KEY);
  372. return Reflect.ownKeys(target);
  373. }
  374. const mutableHandlers = {
  375. get,
  376. set,
  377. deleteProperty,
  378. has,
  379. ownKeys
  380. };
  381. const readonlyHandlers = {
  382. get: readonlyGet,
  383. set(target, key) {
  384. {
  385. console.warn(`Set operation on key "${String(key)}" failed: target is readonly.`, target);
  386. }
  387. return true;
  388. },
  389. deleteProperty(target, key) {
  390. {
  391. console.warn(`Delete operation on key "${String(key)}" failed: target is readonly.`, target);
  392. }
  393. return true;
  394. }
  395. };
  396. const shallowReactiveHandlers = extend({}, mutableHandlers, {
  397. get: shallowGet,
  398. set: shallowSet
  399. });
  400. // Props handlers are special in the sense that it should not unwrap top-level
  401. // refs (in order to allow refs to be explicitly passed down), but should
  402. // retain the reactivity of the normal readonly object.
  403. const shallowReadonlyHandlers = extend({}, readonlyHandlers, {
  404. get: shallowReadonlyGet
  405. });
  406. const toReactive = (value) => isObject(value) ? reactive(value) : value;
  407. const toReadonly = (value) => isObject(value) ? readonly(value) : value;
  408. const toShallow = (value) => value;
  409. const getProto = (v) => Reflect.getPrototypeOf(v);
  410. function get$1(target, key, isReadonly = false, isShallow = false) {
  411. // #1772: readonly(reactive(Map)) should return readonly + reactive version
  412. // of the value
  413. target = target["__v_raw" /* RAW */];
  414. const rawTarget = toRaw(target);
  415. const rawKey = toRaw(key);
  416. if (key !== rawKey) {
  417. !isReadonly && track(rawTarget, "get" /* GET */, key);
  418. }
  419. !isReadonly && track(rawTarget, "get" /* GET */, rawKey);
  420. const { has } = getProto(rawTarget);
  421. const wrap = isReadonly ? toReadonly : isShallow ? toShallow : toReactive;
  422. if (has.call(rawTarget, key)) {
  423. return wrap(target.get(key));
  424. }
  425. else if (has.call(rawTarget, rawKey)) {
  426. return wrap(target.get(rawKey));
  427. }
  428. }
  429. function has$1(key, isReadonly = false) {
  430. const target = this["__v_raw" /* RAW */];
  431. const rawTarget = toRaw(target);
  432. const rawKey = toRaw(key);
  433. if (key !== rawKey) {
  434. !isReadonly && track(rawTarget, "has" /* HAS */, key);
  435. }
  436. !isReadonly && track(rawTarget, "has" /* HAS */, rawKey);
  437. return key === rawKey
  438. ? target.has(key)
  439. : target.has(key) || target.has(rawKey);
  440. }
  441. function size(target, isReadonly = false) {
  442. target = target["__v_raw" /* RAW */];
  443. !isReadonly && track(toRaw(target), "iterate" /* ITERATE */, ITERATE_KEY);
  444. return Reflect.get(target, 'size', target);
  445. }
  446. function add(value) {
  447. value = toRaw(value);
  448. const target = toRaw(this);
  449. const proto = getProto(target);
  450. const hadKey = proto.has.call(target, value);
  451. target.add(value);
  452. if (!hadKey) {
  453. trigger(target, "add" /* ADD */, value, value);
  454. }
  455. return this;
  456. }
  457. function set$1(key, value) {
  458. value = toRaw(value);
  459. const target = toRaw(this);
  460. const { has, get } = getProto(target);
  461. let hadKey = has.call(target, key);
  462. if (!hadKey) {
  463. key = toRaw(key);
  464. hadKey = has.call(target, key);
  465. }
  466. else {
  467. checkIdentityKeys(target, has, key);
  468. }
  469. const oldValue = get.call(target, key);
  470. target.set(key, value);
  471. if (!hadKey) {
  472. trigger(target, "add" /* ADD */, key, value);
  473. }
  474. else if (hasChanged(value, oldValue)) {
  475. trigger(target, "set" /* SET */, key, value, oldValue);
  476. }
  477. return this;
  478. }
  479. function deleteEntry(key) {
  480. const target = toRaw(this);
  481. const { has, get } = getProto(target);
  482. let hadKey = has.call(target, key);
  483. if (!hadKey) {
  484. key = toRaw(key);
  485. hadKey = has.call(target, key);
  486. }
  487. else {
  488. checkIdentityKeys(target, has, key);
  489. }
  490. const oldValue = get ? get.call(target, key) : undefined;
  491. // forward the operation before queueing reactions
  492. const result = target.delete(key);
  493. if (hadKey) {
  494. trigger(target, "delete" /* DELETE */, key, undefined, oldValue);
  495. }
  496. return result;
  497. }
  498. function clear() {
  499. const target = toRaw(this);
  500. const hadItems = target.size !== 0;
  501. const oldTarget = isMap(target)
  502. ? new Map(target)
  503. : new Set(target)
  504. ;
  505. // forward the operation before queueing reactions
  506. const result = target.clear();
  507. if (hadItems) {
  508. trigger(target, "clear" /* CLEAR */, undefined, undefined, oldTarget);
  509. }
  510. return result;
  511. }
  512. function createForEach(isReadonly, isShallow) {
  513. return function forEach(callback, thisArg) {
  514. const observed = this;
  515. const target = observed["__v_raw" /* RAW */];
  516. const rawTarget = toRaw(target);
  517. const wrap = isReadonly ? toReadonly : isShallow ? toShallow : toReactive;
  518. !isReadonly && track(rawTarget, "iterate" /* ITERATE */, ITERATE_KEY);
  519. return target.forEach((value, key) => {
  520. // important: make sure the callback is
  521. // 1. invoked with the reactive map as `this` and 3rd arg
  522. // 2. the value received should be a corresponding reactive/readonly.
  523. return callback.call(thisArg, wrap(value), wrap(key), observed);
  524. });
  525. };
  526. }
  527. function createIterableMethod(method, isReadonly, isShallow) {
  528. return function (...args) {
  529. const target = this["__v_raw" /* RAW */];
  530. const rawTarget = toRaw(target);
  531. const targetIsMap = isMap(rawTarget);
  532. const isPair = method === 'entries' || (method === Symbol.iterator && targetIsMap);
  533. const isKeyOnly = method === 'keys' && targetIsMap;
  534. const innerIterator = target[method](...args);
  535. const wrap = isReadonly ? toReadonly : isShallow ? toShallow : toReactive;
  536. !isReadonly &&
  537. track(rawTarget, "iterate" /* ITERATE */, isKeyOnly ? MAP_KEY_ITERATE_KEY : ITERATE_KEY);
  538. // return a wrapped iterator which returns observed versions of the
  539. // values emitted from the real iterator
  540. return {
  541. // iterator protocol
  542. next() {
  543. const { value, done } = innerIterator.next();
  544. return done
  545. ? { value, done }
  546. : {
  547. value: isPair ? [wrap(value[0]), wrap(value[1])] : wrap(value),
  548. done
  549. };
  550. },
  551. // iterable protocol
  552. [Symbol.iterator]() {
  553. return this;
  554. }
  555. };
  556. };
  557. }
  558. function createReadonlyMethod(type) {
  559. return function (...args) {
  560. {
  561. const key = args[0] ? `on key "${args[0]}" ` : ``;
  562. console.warn(`${capitalize(type)} operation ${key}failed: target is readonly.`, toRaw(this));
  563. }
  564. return type === "delete" /* DELETE */ ? false : this;
  565. };
  566. }
  567. const mutableInstrumentations = {
  568. get(key) {
  569. return get$1(this, key);
  570. },
  571. get size() {
  572. return size(this);
  573. },
  574. has: has$1,
  575. add,
  576. set: set$1,
  577. delete: deleteEntry,
  578. clear,
  579. forEach: createForEach(false, false)
  580. };
  581. const shallowInstrumentations = {
  582. get(key) {
  583. return get$1(this, key, false, true);
  584. },
  585. get size() {
  586. return size(this);
  587. },
  588. has: has$1,
  589. add,
  590. set: set$1,
  591. delete: deleteEntry,
  592. clear,
  593. forEach: createForEach(false, true)
  594. };
  595. const readonlyInstrumentations = {
  596. get(key) {
  597. return get$1(this, key, true);
  598. },
  599. get size() {
  600. return size(this, true);
  601. },
  602. has(key) {
  603. return has$1.call(this, key, true);
  604. },
  605. add: createReadonlyMethod("add" /* ADD */),
  606. set: createReadonlyMethod("set" /* SET */),
  607. delete: createReadonlyMethod("delete" /* DELETE */),
  608. clear: createReadonlyMethod("clear" /* CLEAR */),
  609. forEach: createForEach(true, false)
  610. };
  611. const iteratorMethods = ['keys', 'values', 'entries', Symbol.iterator];
  612. iteratorMethods.forEach(method => {
  613. mutableInstrumentations[method] = createIterableMethod(method, false, false);
  614. readonlyInstrumentations[method] = createIterableMethod(method, true, false);
  615. shallowInstrumentations[method] = createIterableMethod(method, false, true);
  616. });
  617. function createInstrumentationGetter(isReadonly, shallow) {
  618. const instrumentations = shallow
  619. ? shallowInstrumentations
  620. : isReadonly
  621. ? readonlyInstrumentations
  622. : mutableInstrumentations;
  623. return (target, key, receiver) => {
  624. if (key === "__v_isReactive" /* IS_REACTIVE */) {
  625. return !isReadonly;
  626. }
  627. else if (key === "__v_isReadonly" /* IS_READONLY */) {
  628. return isReadonly;
  629. }
  630. else if (key === "__v_raw" /* RAW */) {
  631. return target;
  632. }
  633. return Reflect.get(hasOwn(instrumentations, key) && key in target
  634. ? instrumentations
  635. : target, key, receiver);
  636. };
  637. }
  638. const mutableCollectionHandlers = {
  639. get: createInstrumentationGetter(false, false)
  640. };
  641. const shallowCollectionHandlers = {
  642. get: createInstrumentationGetter(false, true)
  643. };
  644. const readonlyCollectionHandlers = {
  645. get: createInstrumentationGetter(true, false)
  646. };
  647. function checkIdentityKeys(target, has, key) {
  648. const rawKey = toRaw(key);
  649. if (rawKey !== key && has.call(target, rawKey)) {
  650. const type = toRawType(target);
  651. console.warn(`Reactive ${type} contains both the raw and reactive ` +
  652. `versions of the same object${type === `Map` ? ` as keys` : ``}, ` +
  653. `which can lead to inconsistencies. ` +
  654. `Avoid differentiating between the raw and reactive versions ` +
  655. `of an object and only use the reactive version if possible.`);
  656. }
  657. }
  658. const reactiveMap = new WeakMap();
  659. const readonlyMap = new WeakMap();
  660. function targetTypeMap(rawType) {
  661. switch (rawType) {
  662. case 'Object':
  663. case 'Array':
  664. return 1 /* COMMON */;
  665. case 'Map':
  666. case 'Set':
  667. case 'WeakMap':
  668. case 'WeakSet':
  669. return 2 /* COLLECTION */;
  670. default:
  671. return 0 /* INVALID */;
  672. }
  673. }
  674. function getTargetType(value) {
  675. return value["__v_skip" /* SKIP */] || !Object.isExtensible(value)
  676. ? 0 /* INVALID */
  677. : targetTypeMap(toRawType(value));
  678. }
  679. function reactive(target) {
  680. // if trying to observe a readonly proxy, return the readonly version.
  681. if (target && target["__v_isReadonly" /* IS_READONLY */]) {
  682. return target;
  683. }
  684. return createReactiveObject(target, false, mutableHandlers, mutableCollectionHandlers);
  685. }
  686. /**
  687. * Return a shallowly-reactive copy of the original object, where only the root
  688. * level properties are reactive. It also does not auto-unwrap refs (even at the
  689. * root level).
  690. */
  691. function shallowReactive(target) {
  692. return createReactiveObject(target, false, shallowReactiveHandlers, shallowCollectionHandlers);
  693. }
  694. /**
  695. * Creates a readonly copy of the original object. Note the returned copy is not
  696. * made reactive, but `readonly` can be called on an already reactive object.
  697. */
  698. function readonly(target) {
  699. return createReactiveObject(target, true, readonlyHandlers, readonlyCollectionHandlers);
  700. }
  701. /**
  702. * Returns a reactive-copy of the original object, where only the root level
  703. * properties are readonly, and does NOT unwrap refs nor recursively convert
  704. * returned properties.
  705. * This is used for creating the props proxy object for stateful components.
  706. */
  707. function shallowReadonly(target) {
  708. return createReactiveObject(target, true, shallowReadonlyHandlers, readonlyCollectionHandlers);
  709. }
  710. function createReactiveObject(target, isReadonly, baseHandlers, collectionHandlers) {
  711. if (!isObject(target)) {
  712. {
  713. console.warn(`value cannot be made reactive: ${String(target)}`);
  714. }
  715. return target;
  716. }
  717. // target is already a Proxy, return it.
  718. // exception: calling readonly() on a reactive object
  719. if (target["__v_raw" /* RAW */] &&
  720. !(isReadonly && target["__v_isReactive" /* IS_REACTIVE */])) {
  721. return target;
  722. }
  723. // target already has corresponding Proxy
  724. const proxyMap = isReadonly ? readonlyMap : reactiveMap;
  725. const existingProxy = proxyMap.get(target);
  726. if (existingProxy) {
  727. return existingProxy;
  728. }
  729. // only a whitelist of value types can be observed.
  730. const targetType = getTargetType(target);
  731. if (targetType === 0 /* INVALID */) {
  732. return target;
  733. }
  734. const proxy = new Proxy(target, targetType === 2 /* COLLECTION */ ? collectionHandlers : baseHandlers);
  735. proxyMap.set(target, proxy);
  736. return proxy;
  737. }
  738. function isReactive(value) {
  739. if (isReadonly(value)) {
  740. return isReactive(value["__v_raw" /* RAW */]);
  741. }
  742. return !!(value && value["__v_isReactive" /* IS_REACTIVE */]);
  743. }
  744. function isReadonly(value) {
  745. return !!(value && value["__v_isReadonly" /* IS_READONLY */]);
  746. }
  747. function isProxy(value) {
  748. return isReactive(value) || isReadonly(value);
  749. }
  750. function toRaw(observed) {
  751. return ((observed && toRaw(observed["__v_raw" /* RAW */])) || observed);
  752. }
  753. function markRaw(value) {
  754. def(value, "__v_skip" /* SKIP */, true);
  755. return value;
  756. }
  757. const convert = (val) => isObject(val) ? reactive(val) : val;
  758. function isRef(r) {
  759. return Boolean(r && r.__v_isRef === true);
  760. }
  761. function ref(value) {
  762. return createRef(value);
  763. }
  764. function shallowRef(value) {
  765. return createRef(value, true);
  766. }
  767. class RefImpl {
  768. constructor(_rawValue, _shallow = false) {
  769. this._rawValue = _rawValue;
  770. this._shallow = _shallow;
  771. this.__v_isRef = true;
  772. this._value = _shallow ? _rawValue : convert(_rawValue);
  773. }
  774. get value() {
  775. track(toRaw(this), "get" /* GET */, 'value');
  776. return this._value;
  777. }
  778. set value(newVal) {
  779. if (hasChanged(toRaw(newVal), this._rawValue)) {
  780. this._rawValue = newVal;
  781. this._value = this._shallow ? newVal : convert(newVal);
  782. trigger(toRaw(this), "set" /* SET */, 'value', newVal);
  783. }
  784. }
  785. }
  786. function createRef(rawValue, shallow = false) {
  787. if (isRef(rawValue)) {
  788. return rawValue;
  789. }
  790. return new RefImpl(rawValue, shallow);
  791. }
  792. function triggerRef(ref) {
  793. trigger(toRaw(ref), "set" /* SET */, 'value', ref.value );
  794. }
  795. function unref(ref) {
  796. return isRef(ref) ? ref.value : ref;
  797. }
  798. const shallowUnwrapHandlers = {
  799. get: (target, key, receiver) => unref(Reflect.get(target, key, receiver)),
  800. set: (target, key, value, receiver) => {
  801. const oldValue = target[key];
  802. if (isRef(oldValue) && !isRef(value)) {
  803. oldValue.value = value;
  804. return true;
  805. }
  806. else {
  807. return Reflect.set(target, key, value, receiver);
  808. }
  809. }
  810. };
  811. function proxyRefs(objectWithRefs) {
  812. return isReactive(objectWithRefs)
  813. ? objectWithRefs
  814. : new Proxy(objectWithRefs, shallowUnwrapHandlers);
  815. }
  816. class CustomRefImpl {
  817. constructor(factory) {
  818. this.__v_isRef = true;
  819. const { get, set } = factory(() => track(this, "get" /* GET */, 'value'), () => trigger(this, "set" /* SET */, 'value'));
  820. this._get = get;
  821. this._set = set;
  822. }
  823. get value() {
  824. return this._get();
  825. }
  826. set value(newVal) {
  827. this._set(newVal);
  828. }
  829. }
  830. function customRef(factory) {
  831. return new CustomRefImpl(factory);
  832. }
  833. function toRefs(object) {
  834. if (!isProxy(object)) {
  835. console.warn(`toRefs() expects a reactive object but received a plain one.`);
  836. }
  837. const ret = isArray(object) ? new Array(object.length) : {};
  838. for (const key in object) {
  839. ret[key] = toRef(object, key);
  840. }
  841. return ret;
  842. }
  843. class ObjectRefImpl {
  844. constructor(_object, _key) {
  845. this._object = _object;
  846. this._key = _key;
  847. this.__v_isRef = true;
  848. }
  849. get value() {
  850. return this._object[this._key];
  851. }
  852. set value(newVal) {
  853. this._object[this._key] = newVal;
  854. }
  855. }
  856. function toRef(object, key) {
  857. return isRef(object[key])
  858. ? object[key]
  859. : new ObjectRefImpl(object, key);
  860. }
  861. class ComputedRefImpl {
  862. constructor(getter, _setter, isReadonly) {
  863. this._setter = _setter;
  864. this._dirty = true;
  865. this.__v_isRef = true;
  866. this.effect = effect(getter, {
  867. lazy: true,
  868. scheduler: () => {
  869. if (!this._dirty) {
  870. this._dirty = true;
  871. trigger(toRaw(this), "set" /* SET */, 'value');
  872. }
  873. }
  874. });
  875. this["__v_isReadonly" /* IS_READONLY */] = isReadonly;
  876. }
  877. get value() {
  878. if (this._dirty) {
  879. this._value = this.effect();
  880. this._dirty = false;
  881. }
  882. track(toRaw(this), "get" /* GET */, 'value');
  883. return this._value;
  884. }
  885. set value(newValue) {
  886. this._setter(newValue);
  887. }
  888. }
  889. function computed(getterOrOptions) {
  890. let getter;
  891. let setter;
  892. if (isFunction(getterOrOptions)) {
  893. getter = getterOrOptions;
  894. setter = () => {
  895. console.warn('Write operation failed: computed value is readonly');
  896. }
  897. ;
  898. }
  899. else {
  900. getter = getterOrOptions.get;
  901. setter = getterOrOptions.set;
  902. }
  903. return new ComputedRefImpl(getter, setter, isFunction(getterOrOptions) || !getterOrOptions.set);
  904. }
  905. exports.ITERATE_KEY = ITERATE_KEY;
  906. exports.computed = computed;
  907. exports.customRef = customRef;
  908. exports.effect = effect;
  909. exports.enableTracking = enableTracking;
  910. exports.isProxy = isProxy;
  911. exports.isReactive = isReactive;
  912. exports.isReadonly = isReadonly;
  913. exports.isRef = isRef;
  914. exports.markRaw = markRaw;
  915. exports.pauseTracking = pauseTracking;
  916. exports.proxyRefs = proxyRefs;
  917. exports.reactive = reactive;
  918. exports.readonly = readonly;
  919. exports.ref = ref;
  920. exports.resetTracking = resetTracking;
  921. exports.shallowReactive = shallowReactive;
  922. exports.shallowReadonly = shallowReadonly;
  923. exports.shallowRef = shallowRef;
  924. exports.stop = stop;
  925. exports.toRaw = toRaw;
  926. exports.toRef = toRef;
  927. exports.toRefs = toRefs;
  928. exports.track = track;
  929. exports.trigger = trigger;
  930. exports.triggerRef = triggerRef;
  931. exports.unref = unref;
  932. Object.defineProperty(exports, '__esModule', { value: true });
  933. return exports;
  934. }({}));