reactivity.global.js 31 KB

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