@lwc/engine-core 2.20.4 → 2.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -216,11 +216,28 @@ class ReactiveObserver {
216
216
  * SPDX-License-Identifier: MIT
217
217
  * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
218
218
  */
219
+ const DUMMY_REACTIVE_OBSERVER = {
220
+ observe(job) {
221
+ job();
222
+ },
223
+ reset() { },
224
+ link() { },
225
+ };
219
226
  function componentValueMutated(vm, key) {
220
- valueMutated(vm.component, key);
227
+ // On the server side, we don't need mutation tracking. Skipping it improves performance.
228
+ if (process.env.IS_BROWSER) {
229
+ valueMutated(vm.component, key);
230
+ }
221
231
  }
222
232
  function componentValueObserved(vm, key) {
223
- valueObserved(vm.component, key);
233
+ // On the server side, we don't need mutation tracking. Skipping it improves performance.
234
+ if (process.env.IS_BROWSER) {
235
+ valueObserved(vm.component, key);
236
+ }
237
+ }
238
+ function createReactiveObserver(callback) {
239
+ // On the server side, we don't need mutation tracking. Skipping it improves performance.
240
+ return process.env.IS_BROWSER ? new ReactiveObserver(callback) : DUMMY_REACTIVE_OBSERVER;
224
241
  }
225
242
 
226
243
  /*
@@ -1342,7 +1359,24 @@ const reactiveMembrane = new ObservableMembrane({
1342
1359
  * change or being removed.
1343
1360
  */
1344
1361
  function unwrap(value) {
1345
- return reactiveMembrane.unwrapProxy(value);
1362
+ // On the server side, we don't need mutation tracking. Skipping it improves performance.
1363
+ return process.env.IS_BROWSER ? reactiveMembrane.unwrapProxy(value) : value;
1364
+ }
1365
+ function getReadOnlyProxy(value) {
1366
+ // We must return a frozen wrapper around the value, so that child components cannot mutate properties passed to
1367
+ // them from their parents. This applies to both the client and server.
1368
+ return reactiveMembrane.getReadOnlyProxy(value);
1369
+ }
1370
+ function getReactiveProxy(value) {
1371
+ // On the server side, we don't need mutation tracking. Skipping it improves performance.
1372
+ return process.env.IS_BROWSER ? reactiveMembrane.getProxy(value) : value;
1373
+ }
1374
+ // Making the component instance a live value when using Locker to support expandos.
1375
+ function markLockerLiveObject(obj) {
1376
+ // On the server side, we don't need mutation tracking. Skipping it improves performance.
1377
+ if (process.env.IS_BROWSER) {
1378
+ obj[lockerLivePropertyKey] = undefined;
1379
+ }
1346
1380
  }
1347
1381
 
1348
1382
  /*
@@ -1432,8 +1466,7 @@ const LightningElement = function () {
1432
1466
  vm.setHook = setHook;
1433
1467
  vm.getHook = getHook;
1434
1468
  }
1435
- // Making the component instance a live value when using Locker to support expandos.
1436
- this[lockerLivePropertyKey] = undefined;
1469
+ markLockerLiveObject(this);
1437
1470
  // Linking elm, shadow root and component with the VM.
1438
1471
  associateVM(component, vm);
1439
1472
  associateVM(elm, vm);
@@ -1703,6 +1736,60 @@ function createObservedFieldPropertyDescriptor(key) {
1703
1736
  };
1704
1737
  }
1705
1738
 
1739
+ /*
1740
+ * Copyright (c) 2018, salesforce.com, inc.
1741
+ * All rights reserved.
1742
+ * SPDX-License-Identifier: MIT
1743
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
1744
+ */
1745
+ const DUMMY_ACCESSOR_REACTIVE_OBSERVER = {
1746
+ observe(job) {
1747
+ job();
1748
+ },
1749
+ reset() { },
1750
+ link() { },
1751
+ };
1752
+ class AccessorReactiveObserver extends ReactiveObserver {
1753
+ constructor(vm, set) {
1754
+ super(() => {
1755
+ if (shared.isFalse(this.debouncing)) {
1756
+ this.debouncing = true;
1757
+ addCallbackToNextTick(() => {
1758
+ if (shared.isTrue(this.debouncing)) {
1759
+ const { value } = this;
1760
+ const { isDirty: dirtyStateBeforeSetterCall, component, idx } = vm;
1761
+ set.call(component, value);
1762
+ // de-bouncing after the call to the original setter to prevent
1763
+ // infinity loop if the setter itself is mutating things that
1764
+ // were accessed during the previous invocation.
1765
+ this.debouncing = false;
1766
+ if (shared.isTrue(vm.isDirty) && shared.isFalse(dirtyStateBeforeSetterCall) && idx > 0) {
1767
+ // immediate rehydration due to a setter driven mutation, otherwise
1768
+ // the component will get rendered on the second tick, which it is not
1769
+ // desirable.
1770
+ rerenderVM(vm);
1771
+ }
1772
+ }
1773
+ });
1774
+ }
1775
+ });
1776
+ this.debouncing = false;
1777
+ }
1778
+ reset(value) {
1779
+ super.reset();
1780
+ this.debouncing = false;
1781
+ if (arguments.length > 0) {
1782
+ this.value = value;
1783
+ }
1784
+ }
1785
+ }
1786
+ function createAccessorReactiveObserver(vm, set) {
1787
+ // On the server side, we don't need mutation tracking. Skipping it improves performance.
1788
+ return process.env.IS_BROWSER
1789
+ ? new AccessorReactiveObserver(vm, set)
1790
+ : DUMMY_ACCESSOR_REACTIVE_OBSERVER;
1791
+ }
1792
+
1706
1793
  /*
1707
1794
  * Copyright (c) 2018, salesforce.com, inc.
1708
1795
  * All rights reserved.
@@ -1750,50 +1837,6 @@ function createPublicPropertyDescriptor(key) {
1750
1837
  configurable: true
1751
1838
  };
1752
1839
  }
1753
- class AccessorReactiveObserver extends ReactiveObserver {
1754
- constructor(vm, set) {
1755
- super(() => {
1756
- if (shared.isFalse(this.debouncing)) {
1757
- this.debouncing = true;
1758
- addCallbackToNextTick(() => {
1759
- if (shared.isTrue(this.debouncing)) {
1760
- const {
1761
- value
1762
- } = this;
1763
- const {
1764
- isDirty: dirtyStateBeforeSetterCall,
1765
- component,
1766
- idx
1767
- } = vm;
1768
- set.call(component, value); // de-bouncing after the call to the original setter to prevent
1769
- // infinity loop if the setter itself is mutating things that
1770
- // were accessed during the previous invocation.
1771
-
1772
- this.debouncing = false;
1773
-
1774
- if (shared.isTrue(vm.isDirty) && shared.isFalse(dirtyStateBeforeSetterCall) && idx > 0) {
1775
- // immediate rehydration due to a setter driven mutation, otherwise
1776
- // the component will get rendered on the second tick, which it is not
1777
- // desirable.
1778
- rerenderVM(vm);
1779
- }
1780
- }
1781
- });
1782
- }
1783
- });
1784
- this.debouncing = false;
1785
- }
1786
-
1787
- reset(value) {
1788
- super.reset();
1789
- this.debouncing = false;
1790
-
1791
- if (arguments.length > 0) {
1792
- this.value = value;
1793
- }
1794
- }
1795
-
1796
- }
1797
1840
  function createPublicAccessorDescriptor(key, descriptor) {
1798
1841
  const {
1799
1842
  get,
@@ -1834,7 +1877,7 @@ function createPublicAccessorDescriptor(key, descriptor) {
1834
1877
  let ro = vm.oar[key];
1835
1878
 
1836
1879
  if (shared.isUndefined(ro)) {
1837
- ro = vm.oar[key] = new AccessorReactiveObserver(vm, set);
1880
+ ro = vm.oar[key] = createAccessorReactiveObserver(vm, set);
1838
1881
  } // every time we invoke this setter from outside (through this wrapper setter)
1839
1882
  // we should reset the value and then debounce just in case there is a pending
1840
1883
  // invocation the next tick that is not longer relevant since the value is changing
@@ -1866,7 +1909,7 @@ function createPublicAccessorDescriptor(key, descriptor) {
1866
1909
  */
1867
1910
  function track(target) {
1868
1911
  if (arguments.length === 1) {
1869
- return reactiveMembrane.getProxy(target);
1912
+ return getReactiveProxy(target);
1870
1913
  }
1871
1914
  if (process.env.NODE_ENV !== 'production') {
1872
1915
  shared.assert.fail(`@track decorator can only be used with one argument to return a trackable object, or as a decorator function.`);
@@ -1887,7 +1930,7 @@ function internalTrackDecorator(key) {
1887
1930
  shared.assert.invariant(!isInvokingRender, `${vmBeingRendered}.render() method has side effects on the state of ${vm}.${shared.toString(key)}`);
1888
1931
  shared.assert.invariant(!isUpdatingTemplate, `Updating the template of ${vmBeingRendered} has side effects on the state of ${vm}.${shared.toString(key)}`);
1889
1932
  }
1890
- const reactiveOrAnyValue = reactiveMembrane.getProxy(newValue);
1933
+ const reactiveOrAnyValue = getReactiveProxy(newValue);
1891
1934
  if (reactiveOrAnyValue !== vm.cmpFields[key]) {
1892
1935
  vm.cmpFields[key] = reactiveOrAnyValue;
1893
1936
  componentValueMutated(vm, key);
@@ -2279,7 +2322,7 @@ function createSetter(key) {
2279
2322
  fn = cachedSetterByKey[key] = function (newValue) {
2280
2323
  const vm = getAssociatedVM(this);
2281
2324
  const { setHook } = vm;
2282
- newValue = reactiveMembrane.getReadOnlyProxy(newValue);
2325
+ newValue = getReadOnlyProxy(newValue);
2283
2326
  setHook(vm.component, key, newValue);
2284
2327
  };
2285
2328
  }
@@ -3419,10 +3462,11 @@ function mountElement(vnode, parent, anchor, renderer) {
3419
3462
  const { sel, owner, data: { svg }, } = vnode;
3420
3463
  const { createElement } = renderer;
3421
3464
  const namespace = shared.isTrue(svg) ? shared.SVG_NAMESPACE : undefined;
3422
- const elm = createElement(sel, namespace);
3465
+ const elm = (vnode.elm = createElement(sel, namespace));
3423
3466
  linkNodeToShadow(elm, owner, renderer);
3424
- fallbackElmHook(elm, vnode, renderer);
3425
- vnode.elm = elm;
3467
+ applyStyleScoping(elm, owner, renderer);
3468
+ applyDomManual(elm, vnode);
3469
+ applyElementRestrictions(elm, vnode);
3426
3470
  patchElementPropsAndAttrs$1(null, vnode, renderer);
3427
3471
  insertNode(elm, parent, anchor, renderer);
3428
3472
  mountVNodes(vnode.children, elm, renderer, null);
@@ -3437,6 +3481,7 @@ function mountStatic(vnode, parent, anchor, renderer) {
3437
3481
  const { cloneNode, isSyntheticShadowDefined } = renderer;
3438
3482
  const elm = (vnode.elm = cloneNode(vnode.fragment, true));
3439
3483
  linkNodeToShadow(elm, owner, renderer);
3484
+ applyElementRestrictions(elm, vnode);
3440
3485
  // Marks this node as Static to propagate the shadow resolver. must happen after elm is assigned to the proper shadow
3441
3486
  const { renderMode, shadowMode } = owner;
3442
3487
  if (isSyntheticShadowDefined) {
@@ -3444,10 +3489,6 @@ function mountStatic(vnode, parent, anchor, renderer) {
3444
3489
  elm[shared.KEY__SHADOW_STATIC] = true;
3445
3490
  }
3446
3491
  }
3447
- if (process.env.NODE_ENV !== 'production') {
3448
- const isLight = renderMode === 0 /* RenderMode.Light */;
3449
- patchElementWithRestrictions(elm, { isPortal: false, isLight });
3450
- }
3451
3492
  insertNode(elm, parent, anchor, renderer);
3452
3493
  }
3453
3494
  function mountCustomElement(vnode, parent, anchor, renderer) {
@@ -3464,9 +3505,10 @@ function mountCustomElement(vnode, parent, anchor, renderer) {
3464
3505
  // the custom element from the registry is expecting an upgrade callback
3465
3506
  vm = createViewModelHook(elm, vnode, renderer);
3466
3507
  });
3467
- linkNodeToShadow(elm, owner, renderer);
3468
3508
  vnode.elm = elm;
3469
3509
  vnode.vm = vm;
3510
+ linkNodeToShadow(elm, owner, renderer);
3511
+ applyStyleScoping(elm, owner, renderer);
3470
3512
  if (vm) {
3471
3513
  allocateChildren(vnode, vm);
3472
3514
  }
@@ -3550,22 +3592,6 @@ function unmountVNodes(vnodes, parent, renderer, doRemove = false, start = 0, en
3550
3592
  function isVNode(vnode) {
3551
3593
  return vnode != null;
3552
3594
  }
3553
- function observeElementChildNodes(elm) {
3554
- elm.$domManual$ = true;
3555
- }
3556
- function setElementShadowToken(elm, token) {
3557
- elm.$shadowToken$ = token;
3558
- }
3559
- // Set the scope token class for *.scoped.css styles
3560
- function setScopeTokenClassIfNecessary(elm, owner, renderer) {
3561
- const token = getScopeTokenClass(owner);
3562
- if (!shared.isNull(token)) {
3563
- const { getClassList } = renderer;
3564
- // TODO [#2762]: this dot notation with add is probably problematic
3565
- // probably we should have a renderer api for just the add operation
3566
- getClassList(elm).add(token);
3567
- }
3568
- }
3569
3595
  function linkNodeToShadow(elm, owner, renderer) {
3570
3596
  const { renderRoot, renderMode, shadowMode } = owner;
3571
3597
  const { isSyntheticShadowDefined } = renderer;
@@ -3618,31 +3644,37 @@ function patchElementPropsAndAttrs$1(oldVnode, vnode, renderer) {
3618
3644
  patchAttributes(oldVnode, vnode, renderer);
3619
3645
  patchProps(oldVnode, vnode, renderer);
3620
3646
  }
3621
- function fallbackElmHook(elm, vnode, renderer) {
3622
- const { owner } = vnode;
3623
- setScopeTokenClassIfNecessary(elm, owner, renderer);
3624
- if (owner.shadowMode === 1 /* ShadowMode.Synthetic */) {
3625
- const { data: { context }, } = vnode;
3626
- const { stylesheetToken } = owner.context;
3627
- if (!shared.isUndefined(context) &&
3628
- !shared.isUndefined(context.lwc) &&
3629
- context.lwc.dom === "manual" /* LwcDomMode.Manual */) {
3630
- // this element will now accept any manual content inserted into it
3631
- observeElementChildNodes(elm);
3632
- }
3633
- if (!shared.isUndefined(stylesheetToken)) {
3634
- // when running in synthetic shadow mode, we need to set the shadowToken value
3635
- // into each element from the template, so they can be styled accordingly.
3636
- setElementShadowToken(elm, stylesheetToken);
3637
- }
3647
+ function applyStyleScoping(elm, owner, renderer) {
3648
+ // Set the class name for `*.scoped.css` style scoping.
3649
+ const scopeToken = getScopeTokenClass(owner);
3650
+ if (!shared.isNull(scopeToken)) {
3651
+ const { getClassList } = renderer;
3652
+ // TODO [#2762]: this dot notation with add is probably problematic
3653
+ // probably we should have a renderer api for just the add operation
3654
+ getClassList(elm).add(scopeToken);
3655
+ }
3656
+ // Set property element for synthetic shadow DOM style scoping.
3657
+ const { stylesheetToken: syntheticToken } = owner.context;
3658
+ if (owner.shadowMode === 1 /* ShadowMode.Synthetic */ && !shared.isUndefined(syntheticToken)) {
3659
+ elm.$shadowToken$ = syntheticToken;
3638
3660
  }
3661
+ }
3662
+ function applyDomManual(elm, vnode) {
3663
+ var _a;
3664
+ const { owner, data: { context }, } = vnode;
3665
+ if (owner.shadowMode === 1 /* ShadowMode.Synthetic */ && ((_a = context === null || context === void 0 ? void 0 : context.lwc) === null || _a === void 0 ? void 0 : _a.dom) === "manual" /* LwcDomMode.Manual */) {
3666
+ elm.$domManual$ = true;
3667
+ }
3668
+ }
3669
+ function applyElementRestrictions(elm, vnode) {
3670
+ var _a, _b;
3639
3671
  if (process.env.NODE_ENV !== 'production') {
3640
- const { data: { context }, } = vnode;
3641
- const isPortal = !shared.isUndefined(context) &&
3642
- !shared.isUndefined(context.lwc) &&
3643
- context.lwc.dom === "manual" /* LwcDomMode.Manual */;
3644
- const isLight = owner.renderMode === 0 /* RenderMode.Light */;
3645
- patchElementWithRestrictions(elm, { isPortal, isLight });
3672
+ const isPortal = vnode.type === 2 /* VNodeType.Element */ && ((_b = (_a = vnode.data.context) === null || _a === void 0 ? void 0 : _a.lwc) === null || _b === void 0 ? void 0 : _b.dom) === "manual" /* LwcDomMode.Manual */;
3673
+ const isLight = vnode.owner.renderMode === 0 /* RenderMode.Light */;
3674
+ patchElementWithRestrictions(elm, {
3675
+ isPortal,
3676
+ isLight,
3677
+ });
3646
3678
  }
3647
3679
  }
3648
3680
  function allocateChildren(vnode, vm) {
@@ -3677,15 +3709,6 @@ function createViewModelHook(elm, vnode, renderer) {
3677
3709
  return vm;
3678
3710
  }
3679
3711
  const { sel, mode, ctor, owner } = vnode;
3680
- setScopeTokenClassIfNecessary(elm, owner, renderer);
3681
- if (owner.shadowMode === 1 /* ShadowMode.Synthetic */) {
3682
- const { stylesheetToken } = owner.context;
3683
- // when running in synthetic shadow mode, we need to set the shadowToken value
3684
- // into each element from the template, so they can be styled accordingly.
3685
- if (!shared.isUndefined(stylesheetToken)) {
3686
- setElementShadowToken(elm, stylesheetToken);
3687
- }
3688
- }
3689
3712
  vm = createVM(elm, ctor, renderer, {
3690
3713
  mode,
3691
3714
  owner,
@@ -4735,7 +4758,7 @@ function getComponentRegisteredTemplate(Ctor) {
4735
4758
  return signedTemplateMap.get(Ctor);
4736
4759
  }
4737
4760
  function getTemplateReactiveObserver(vm) {
4738
- return new ReactiveObserver(() => {
4761
+ return createReactiveObserver(() => {
4739
4762
  const { isDirty } = vm;
4740
4763
  if (shared.isFalse(isDirty)) {
4741
4764
  markComponentAsDirty(vm);
@@ -5550,7 +5573,7 @@ function createMethodDataCallback(vm, method) {
5550
5573
  function createConfigWatcher(component, configCallback, callbackWhenConfigIsReady) {
5551
5574
  let hasPendingConfig = false; // creating the reactive observer for reactive params when needed
5552
5575
 
5553
- const ro = new ReactiveObserver(() => {
5576
+ const ro = createReactiveObserver(() => {
5554
5577
  if (hasPendingConfig === false) {
5555
5578
  hasPendingConfig = true; // collect new config in the micro-task
5556
5579
 
@@ -5846,7 +5869,7 @@ function readonly(obj) {
5846
5869
  shared.assert.fail('@readonly cannot be used as a decorator just yet, use it as a function with one argument to produce a readonly version of the provided value.');
5847
5870
  }
5848
5871
  }
5849
- return reactiveMembrane.getReadOnlyProxy(obj);
5872
+ return getReadOnlyProxy(obj);
5850
5873
  }
5851
5874
 
5852
5875
  /*
@@ -6396,4 +6419,4 @@ exports.swapTemplate = swapTemplate;
6396
6419
  exports.track = track;
6397
6420
  exports.unwrap = unwrap;
6398
6421
  exports.wire = wire;
6399
- /* version: 2.20.4 */
6422
+ /* version: 2.22.0 */
@@ -1,7 +1,7 @@
1
1
  /* proxy-compat-disable */
2
2
  import { runtimeFlags } from '@lwc/features';
3
3
  export { setFeatureFlag, setFeatureFlagForTest } from '@lwc/features';
4
- import { seal, create, isFunction as isFunction$1, ArrayPush as ArrayPush$1, isUndefined as isUndefined$1, ArrayIndexOf, ArraySplice, StringToLowerCase, isNull, ArrayJoin, isFrozen, defineProperty, hasOwnProperty as hasOwnProperty$1, assign, forEach, keys, AriaPropNameToAttrNameMap, getPropertyDescriptor, defineProperties, getOwnPropertyNames as getOwnPropertyNames$1, getPrototypeOf as getPrototypeOf$1, setPrototypeOf, isObject, assert, KEY__SYNTHETIC_MODE, toString as toString$1, isFalse, isTrue, getOwnPropertyDescriptor as getOwnPropertyDescriptor$1, LWC_VERSION_COMMENT_REGEX, LWC_VERSION, freeze, htmlPropertyToAttribute, ArraySlice, ArrayMap, isArray as isArray$1, KEY__SCOPED_CSS, StringCharCodeAt, XML_NAMESPACE, XLINK_NAMESPACE, isString, StringSlice, SVG_NAMESPACE, KEY__SHADOW_STATIC, KEY__SHADOW_RESOLVER, isNumber, StringReplace, noop, ArrayUnshift, ArrayCopyWithin, ArrayFill, ArraySort, ArrayReverse, ArrayShift, ArrayPop } from '@lwc/shared';
4
+ import { seal, create, isFunction as isFunction$1, ArrayPush as ArrayPush$1, isUndefined as isUndefined$1, ArrayIndexOf, ArraySplice, StringToLowerCase, isNull, ArrayJoin, isFrozen, defineProperty, hasOwnProperty as hasOwnProperty$1, assign, forEach, keys, AriaPropNameToAttrNameMap, getPropertyDescriptor, defineProperties, getOwnPropertyNames as getOwnPropertyNames$1, getPrototypeOf as getPrototypeOf$1, setPrototypeOf, isObject, assert, KEY__SYNTHETIC_MODE, isFalse, isTrue, toString as toString$1, getOwnPropertyDescriptor as getOwnPropertyDescriptor$1, LWC_VERSION_COMMENT_REGEX, LWC_VERSION, freeze, htmlPropertyToAttribute, ArraySlice, ArrayMap, isArray as isArray$1, KEY__SCOPED_CSS, StringCharCodeAt, XML_NAMESPACE, XLINK_NAMESPACE, isString, StringSlice, SVG_NAMESPACE, KEY__SHADOW_STATIC, KEY__SHADOW_RESOLVER, isNumber, StringReplace, noop, ArrayUnshift, ArrayCopyWithin, ArrayFill, ArraySort, ArrayReverse, ArrayShift, ArrayPop } from '@lwc/shared';
5
5
 
6
6
  /*
7
7
  * Copyright (c) 2018, salesforce.com, inc.
@@ -213,11 +213,28 @@ class ReactiveObserver {
213
213
  * SPDX-License-Identifier: MIT
214
214
  * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
215
215
  */
216
+ const DUMMY_REACTIVE_OBSERVER = {
217
+ observe(job) {
218
+ job();
219
+ },
220
+ reset() { },
221
+ link() { },
222
+ };
216
223
  function componentValueMutated(vm, key) {
217
- valueMutated(vm.component, key);
224
+ // On the server side, we don't need mutation tracking. Skipping it improves performance.
225
+ if (process.env.IS_BROWSER) {
226
+ valueMutated(vm.component, key);
227
+ }
218
228
  }
219
229
  function componentValueObserved(vm, key) {
220
- valueObserved(vm.component, key);
230
+ // On the server side, we don't need mutation tracking. Skipping it improves performance.
231
+ if (process.env.IS_BROWSER) {
232
+ valueObserved(vm.component, key);
233
+ }
234
+ }
235
+ function createReactiveObserver(callback) {
236
+ // On the server side, we don't need mutation tracking. Skipping it improves performance.
237
+ return process.env.IS_BROWSER ? new ReactiveObserver(callback) : DUMMY_REACTIVE_OBSERVER;
221
238
  }
222
239
 
223
240
  /*
@@ -1339,7 +1356,24 @@ const reactiveMembrane = new ObservableMembrane({
1339
1356
  * change or being removed.
1340
1357
  */
1341
1358
  function unwrap(value) {
1342
- return reactiveMembrane.unwrapProxy(value);
1359
+ // On the server side, we don't need mutation tracking. Skipping it improves performance.
1360
+ return process.env.IS_BROWSER ? reactiveMembrane.unwrapProxy(value) : value;
1361
+ }
1362
+ function getReadOnlyProxy(value) {
1363
+ // We must return a frozen wrapper around the value, so that child components cannot mutate properties passed to
1364
+ // them from their parents. This applies to both the client and server.
1365
+ return reactiveMembrane.getReadOnlyProxy(value);
1366
+ }
1367
+ function getReactiveProxy(value) {
1368
+ // On the server side, we don't need mutation tracking. Skipping it improves performance.
1369
+ return process.env.IS_BROWSER ? reactiveMembrane.getProxy(value) : value;
1370
+ }
1371
+ // Making the component instance a live value when using Locker to support expandos.
1372
+ function markLockerLiveObject(obj) {
1373
+ // On the server side, we don't need mutation tracking. Skipping it improves performance.
1374
+ if (process.env.IS_BROWSER) {
1375
+ obj[lockerLivePropertyKey] = undefined;
1376
+ }
1343
1377
  }
1344
1378
 
1345
1379
  /*
@@ -1429,8 +1463,7 @@ const LightningElement = function () {
1429
1463
  vm.setHook = setHook;
1430
1464
  vm.getHook = getHook;
1431
1465
  }
1432
- // Making the component instance a live value when using Locker to support expandos.
1433
- this[lockerLivePropertyKey] = undefined;
1466
+ markLockerLiveObject(this);
1434
1467
  // Linking elm, shadow root and component with the VM.
1435
1468
  associateVM(component, vm);
1436
1469
  associateVM(elm, vm);
@@ -1700,6 +1733,60 @@ function createObservedFieldPropertyDescriptor(key) {
1700
1733
  };
1701
1734
  }
1702
1735
 
1736
+ /*
1737
+ * Copyright (c) 2018, salesforce.com, inc.
1738
+ * All rights reserved.
1739
+ * SPDX-License-Identifier: MIT
1740
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
1741
+ */
1742
+ const DUMMY_ACCESSOR_REACTIVE_OBSERVER = {
1743
+ observe(job) {
1744
+ job();
1745
+ },
1746
+ reset() { },
1747
+ link() { },
1748
+ };
1749
+ class AccessorReactiveObserver extends ReactiveObserver {
1750
+ constructor(vm, set) {
1751
+ super(() => {
1752
+ if (isFalse(this.debouncing)) {
1753
+ this.debouncing = true;
1754
+ addCallbackToNextTick(() => {
1755
+ if (isTrue(this.debouncing)) {
1756
+ const { value } = this;
1757
+ const { isDirty: dirtyStateBeforeSetterCall, component, idx } = vm;
1758
+ set.call(component, value);
1759
+ // de-bouncing after the call to the original setter to prevent
1760
+ // infinity loop if the setter itself is mutating things that
1761
+ // were accessed during the previous invocation.
1762
+ this.debouncing = false;
1763
+ if (isTrue(vm.isDirty) && isFalse(dirtyStateBeforeSetterCall) && idx > 0) {
1764
+ // immediate rehydration due to a setter driven mutation, otherwise
1765
+ // the component will get rendered on the second tick, which it is not
1766
+ // desirable.
1767
+ rerenderVM(vm);
1768
+ }
1769
+ }
1770
+ });
1771
+ }
1772
+ });
1773
+ this.debouncing = false;
1774
+ }
1775
+ reset(value) {
1776
+ super.reset();
1777
+ this.debouncing = false;
1778
+ if (arguments.length > 0) {
1779
+ this.value = value;
1780
+ }
1781
+ }
1782
+ }
1783
+ function createAccessorReactiveObserver(vm, set) {
1784
+ // On the server side, we don't need mutation tracking. Skipping it improves performance.
1785
+ return process.env.IS_BROWSER
1786
+ ? new AccessorReactiveObserver(vm, set)
1787
+ : DUMMY_ACCESSOR_REACTIVE_OBSERVER;
1788
+ }
1789
+
1703
1790
  /*
1704
1791
  * Copyright (c) 2018, salesforce.com, inc.
1705
1792
  * All rights reserved.
@@ -1747,50 +1834,6 @@ function createPublicPropertyDescriptor(key) {
1747
1834
  configurable: true
1748
1835
  };
1749
1836
  }
1750
- class AccessorReactiveObserver extends ReactiveObserver {
1751
- constructor(vm, set) {
1752
- super(() => {
1753
- if (isFalse(this.debouncing)) {
1754
- this.debouncing = true;
1755
- addCallbackToNextTick(() => {
1756
- if (isTrue(this.debouncing)) {
1757
- const {
1758
- value
1759
- } = this;
1760
- const {
1761
- isDirty: dirtyStateBeforeSetterCall,
1762
- component,
1763
- idx
1764
- } = vm;
1765
- set.call(component, value); // de-bouncing after the call to the original setter to prevent
1766
- // infinity loop if the setter itself is mutating things that
1767
- // were accessed during the previous invocation.
1768
-
1769
- this.debouncing = false;
1770
-
1771
- if (isTrue(vm.isDirty) && isFalse(dirtyStateBeforeSetterCall) && idx > 0) {
1772
- // immediate rehydration due to a setter driven mutation, otherwise
1773
- // the component will get rendered on the second tick, which it is not
1774
- // desirable.
1775
- rerenderVM(vm);
1776
- }
1777
- }
1778
- });
1779
- }
1780
- });
1781
- this.debouncing = false;
1782
- }
1783
-
1784
- reset(value) {
1785
- super.reset();
1786
- this.debouncing = false;
1787
-
1788
- if (arguments.length > 0) {
1789
- this.value = value;
1790
- }
1791
- }
1792
-
1793
- }
1794
1837
  function createPublicAccessorDescriptor(key, descriptor) {
1795
1838
  const {
1796
1839
  get,
@@ -1831,7 +1874,7 @@ function createPublicAccessorDescriptor(key, descriptor) {
1831
1874
  let ro = vm.oar[key];
1832
1875
 
1833
1876
  if (isUndefined$1(ro)) {
1834
- ro = vm.oar[key] = new AccessorReactiveObserver(vm, set);
1877
+ ro = vm.oar[key] = createAccessorReactiveObserver(vm, set);
1835
1878
  } // every time we invoke this setter from outside (through this wrapper setter)
1836
1879
  // we should reset the value and then debounce just in case there is a pending
1837
1880
  // invocation the next tick that is not longer relevant since the value is changing
@@ -1863,7 +1906,7 @@ function createPublicAccessorDescriptor(key, descriptor) {
1863
1906
  */
1864
1907
  function track(target) {
1865
1908
  if (arguments.length === 1) {
1866
- return reactiveMembrane.getProxy(target);
1909
+ return getReactiveProxy(target);
1867
1910
  }
1868
1911
  if (process.env.NODE_ENV !== 'production') {
1869
1912
  assert.fail(`@track decorator can only be used with one argument to return a trackable object, or as a decorator function.`);
@@ -1884,7 +1927,7 @@ function internalTrackDecorator(key) {
1884
1927
  assert.invariant(!isInvokingRender, `${vmBeingRendered}.render() method has side effects on the state of ${vm}.${toString$1(key)}`);
1885
1928
  assert.invariant(!isUpdatingTemplate, `Updating the template of ${vmBeingRendered} has side effects on the state of ${vm}.${toString$1(key)}`);
1886
1929
  }
1887
- const reactiveOrAnyValue = reactiveMembrane.getProxy(newValue);
1930
+ const reactiveOrAnyValue = getReactiveProxy(newValue);
1888
1931
  if (reactiveOrAnyValue !== vm.cmpFields[key]) {
1889
1932
  vm.cmpFields[key] = reactiveOrAnyValue;
1890
1933
  componentValueMutated(vm, key);
@@ -2276,7 +2319,7 @@ function createSetter(key) {
2276
2319
  fn = cachedSetterByKey[key] = function (newValue) {
2277
2320
  const vm = getAssociatedVM(this);
2278
2321
  const { setHook } = vm;
2279
- newValue = reactiveMembrane.getReadOnlyProxy(newValue);
2322
+ newValue = getReadOnlyProxy(newValue);
2280
2323
  setHook(vm.component, key, newValue);
2281
2324
  };
2282
2325
  }
@@ -3416,10 +3459,11 @@ function mountElement(vnode, parent, anchor, renderer) {
3416
3459
  const { sel, owner, data: { svg }, } = vnode;
3417
3460
  const { createElement } = renderer;
3418
3461
  const namespace = isTrue(svg) ? SVG_NAMESPACE : undefined;
3419
- const elm = createElement(sel, namespace);
3462
+ const elm = (vnode.elm = createElement(sel, namespace));
3420
3463
  linkNodeToShadow(elm, owner, renderer);
3421
- fallbackElmHook(elm, vnode, renderer);
3422
- vnode.elm = elm;
3464
+ applyStyleScoping(elm, owner, renderer);
3465
+ applyDomManual(elm, vnode);
3466
+ applyElementRestrictions(elm, vnode);
3423
3467
  patchElementPropsAndAttrs$1(null, vnode, renderer);
3424
3468
  insertNode(elm, parent, anchor, renderer);
3425
3469
  mountVNodes(vnode.children, elm, renderer, null);
@@ -3434,6 +3478,7 @@ function mountStatic(vnode, parent, anchor, renderer) {
3434
3478
  const { cloneNode, isSyntheticShadowDefined } = renderer;
3435
3479
  const elm = (vnode.elm = cloneNode(vnode.fragment, true));
3436
3480
  linkNodeToShadow(elm, owner, renderer);
3481
+ applyElementRestrictions(elm, vnode);
3437
3482
  // Marks this node as Static to propagate the shadow resolver. must happen after elm is assigned to the proper shadow
3438
3483
  const { renderMode, shadowMode } = owner;
3439
3484
  if (isSyntheticShadowDefined) {
@@ -3441,10 +3486,6 @@ function mountStatic(vnode, parent, anchor, renderer) {
3441
3486
  elm[KEY__SHADOW_STATIC] = true;
3442
3487
  }
3443
3488
  }
3444
- if (process.env.NODE_ENV !== 'production') {
3445
- const isLight = renderMode === 0 /* RenderMode.Light */;
3446
- patchElementWithRestrictions(elm, { isPortal: false, isLight });
3447
- }
3448
3489
  insertNode(elm, parent, anchor, renderer);
3449
3490
  }
3450
3491
  function mountCustomElement(vnode, parent, anchor, renderer) {
@@ -3461,9 +3502,10 @@ function mountCustomElement(vnode, parent, anchor, renderer) {
3461
3502
  // the custom element from the registry is expecting an upgrade callback
3462
3503
  vm = createViewModelHook(elm, vnode, renderer);
3463
3504
  });
3464
- linkNodeToShadow(elm, owner, renderer);
3465
3505
  vnode.elm = elm;
3466
3506
  vnode.vm = vm;
3507
+ linkNodeToShadow(elm, owner, renderer);
3508
+ applyStyleScoping(elm, owner, renderer);
3467
3509
  if (vm) {
3468
3510
  allocateChildren(vnode, vm);
3469
3511
  }
@@ -3547,22 +3589,6 @@ function unmountVNodes(vnodes, parent, renderer, doRemove = false, start = 0, en
3547
3589
  function isVNode(vnode) {
3548
3590
  return vnode != null;
3549
3591
  }
3550
- function observeElementChildNodes(elm) {
3551
- elm.$domManual$ = true;
3552
- }
3553
- function setElementShadowToken(elm, token) {
3554
- elm.$shadowToken$ = token;
3555
- }
3556
- // Set the scope token class for *.scoped.css styles
3557
- function setScopeTokenClassIfNecessary(elm, owner, renderer) {
3558
- const token = getScopeTokenClass(owner);
3559
- if (!isNull(token)) {
3560
- const { getClassList } = renderer;
3561
- // TODO [#2762]: this dot notation with add is probably problematic
3562
- // probably we should have a renderer api for just the add operation
3563
- getClassList(elm).add(token);
3564
- }
3565
- }
3566
3592
  function linkNodeToShadow(elm, owner, renderer) {
3567
3593
  const { renderRoot, renderMode, shadowMode } = owner;
3568
3594
  const { isSyntheticShadowDefined } = renderer;
@@ -3615,31 +3641,37 @@ function patchElementPropsAndAttrs$1(oldVnode, vnode, renderer) {
3615
3641
  patchAttributes(oldVnode, vnode, renderer);
3616
3642
  patchProps(oldVnode, vnode, renderer);
3617
3643
  }
3618
- function fallbackElmHook(elm, vnode, renderer) {
3619
- const { owner } = vnode;
3620
- setScopeTokenClassIfNecessary(elm, owner, renderer);
3621
- if (owner.shadowMode === 1 /* ShadowMode.Synthetic */) {
3622
- const { data: { context }, } = vnode;
3623
- const { stylesheetToken } = owner.context;
3624
- if (!isUndefined$1(context) &&
3625
- !isUndefined$1(context.lwc) &&
3626
- context.lwc.dom === "manual" /* LwcDomMode.Manual */) {
3627
- // this element will now accept any manual content inserted into it
3628
- observeElementChildNodes(elm);
3629
- }
3630
- if (!isUndefined$1(stylesheetToken)) {
3631
- // when running in synthetic shadow mode, we need to set the shadowToken value
3632
- // into each element from the template, so they can be styled accordingly.
3633
- setElementShadowToken(elm, stylesheetToken);
3634
- }
3644
+ function applyStyleScoping(elm, owner, renderer) {
3645
+ // Set the class name for `*.scoped.css` style scoping.
3646
+ const scopeToken = getScopeTokenClass(owner);
3647
+ if (!isNull(scopeToken)) {
3648
+ const { getClassList } = renderer;
3649
+ // TODO [#2762]: this dot notation with add is probably problematic
3650
+ // probably we should have a renderer api for just the add operation
3651
+ getClassList(elm).add(scopeToken);
3652
+ }
3653
+ // Set property element for synthetic shadow DOM style scoping.
3654
+ const { stylesheetToken: syntheticToken } = owner.context;
3655
+ if (owner.shadowMode === 1 /* ShadowMode.Synthetic */ && !isUndefined$1(syntheticToken)) {
3656
+ elm.$shadowToken$ = syntheticToken;
3635
3657
  }
3658
+ }
3659
+ function applyDomManual(elm, vnode) {
3660
+ var _a;
3661
+ const { owner, data: { context }, } = vnode;
3662
+ if (owner.shadowMode === 1 /* ShadowMode.Synthetic */ && ((_a = context === null || context === void 0 ? void 0 : context.lwc) === null || _a === void 0 ? void 0 : _a.dom) === "manual" /* LwcDomMode.Manual */) {
3663
+ elm.$domManual$ = true;
3664
+ }
3665
+ }
3666
+ function applyElementRestrictions(elm, vnode) {
3667
+ var _a, _b;
3636
3668
  if (process.env.NODE_ENV !== 'production') {
3637
- const { data: { context }, } = vnode;
3638
- const isPortal = !isUndefined$1(context) &&
3639
- !isUndefined$1(context.lwc) &&
3640
- context.lwc.dom === "manual" /* LwcDomMode.Manual */;
3641
- const isLight = owner.renderMode === 0 /* RenderMode.Light */;
3642
- patchElementWithRestrictions(elm, { isPortal, isLight });
3669
+ const isPortal = vnode.type === 2 /* VNodeType.Element */ && ((_b = (_a = vnode.data.context) === null || _a === void 0 ? void 0 : _a.lwc) === null || _b === void 0 ? void 0 : _b.dom) === "manual" /* LwcDomMode.Manual */;
3670
+ const isLight = vnode.owner.renderMode === 0 /* RenderMode.Light */;
3671
+ patchElementWithRestrictions(elm, {
3672
+ isPortal,
3673
+ isLight,
3674
+ });
3643
3675
  }
3644
3676
  }
3645
3677
  function allocateChildren(vnode, vm) {
@@ -3674,15 +3706,6 @@ function createViewModelHook(elm, vnode, renderer) {
3674
3706
  return vm;
3675
3707
  }
3676
3708
  const { sel, mode, ctor, owner } = vnode;
3677
- setScopeTokenClassIfNecessary(elm, owner, renderer);
3678
- if (owner.shadowMode === 1 /* ShadowMode.Synthetic */) {
3679
- const { stylesheetToken } = owner.context;
3680
- // when running in synthetic shadow mode, we need to set the shadowToken value
3681
- // into each element from the template, so they can be styled accordingly.
3682
- if (!isUndefined$1(stylesheetToken)) {
3683
- setElementShadowToken(elm, stylesheetToken);
3684
- }
3685
- }
3686
3709
  vm = createVM(elm, ctor, renderer, {
3687
3710
  mode,
3688
3711
  owner,
@@ -4732,7 +4755,7 @@ function getComponentRegisteredTemplate(Ctor) {
4732
4755
  return signedTemplateMap.get(Ctor);
4733
4756
  }
4734
4757
  function getTemplateReactiveObserver(vm) {
4735
- return new ReactiveObserver(() => {
4758
+ return createReactiveObserver(() => {
4736
4759
  const { isDirty } = vm;
4737
4760
  if (isFalse(isDirty)) {
4738
4761
  markComponentAsDirty(vm);
@@ -5547,7 +5570,7 @@ function createMethodDataCallback(vm, method) {
5547
5570
  function createConfigWatcher(component, configCallback, callbackWhenConfigIsReady) {
5548
5571
  let hasPendingConfig = false; // creating the reactive observer for reactive params when needed
5549
5572
 
5550
- const ro = new ReactiveObserver(() => {
5573
+ const ro = createReactiveObserver(() => {
5551
5574
  if (hasPendingConfig === false) {
5552
5575
  hasPendingConfig = true; // collect new config in the micro-task
5553
5576
 
@@ -5843,7 +5866,7 @@ function readonly(obj) {
5843
5866
  assert.fail('@readonly cannot be used as a decorator just yet, use it as a function with one argument to produce a readonly version of the provided value.');
5844
5867
  }
5845
5868
  }
5846
- return reactiveMembrane.getReadOnlyProxy(obj);
5869
+ return getReadOnlyProxy(obj);
5847
5870
  }
5848
5871
 
5849
5872
  /*
@@ -6356,4 +6379,4 @@ function getComponentConstructor(elm) {
6356
6379
  }
6357
6380
 
6358
6381
  export { LightningElement, profilerControl as __unstable__ProfilerControl, api$1 as api, connectRootElement, createContextProvider, createVM, disconnectRootElement, freezeTemplate, getAssociatedVMIfPresent, getComponentConstructor, getComponentDef, getComponentHtmlPrototype, getUpgradableConstructor, hydrateRoot, isComponentConstructor, parseFragment, parseSVGFragment, readonly, register, registerComponent, registerDecorators, registerTemplate, sanitizeAttribute, setHooks, swapComponent, swapStyle, swapTemplate, track, unwrap, wire };
6359
- /* version: 2.20.4 */
6382
+ /* version: 2.22.0 */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lwc/engine-core",
3
- "version": "2.20.4",
3
+ "version": "2.22.0",
4
4
  "description": "Core LWC engine APIs.",
5
5
  "homepage": "https://lwc.dev/",
6
6
  "repository": {
@@ -25,8 +25,8 @@
25
25
  "types/"
26
26
  ],
27
27
  "dependencies": {
28
- "@lwc/features": "2.20.4",
29
- "@lwc/shared": "2.20.4"
28
+ "@lwc/features": "2.22.0",
29
+ "@lwc/shared": "2.22.0"
30
30
  },
31
31
  "devDependencies": {
32
32
  "observable-membrane": "2.0.0"
@@ -0,0 +1,9 @@
1
+ import { ReactiveObserver } from '../libs/mutation-tracker';
2
+ import { VM } from './vm';
3
+ export declare class AccessorReactiveObserver extends ReactiveObserver {
4
+ private value;
5
+ private debouncing;
6
+ constructor(vm: VM, set: (v: any) => void);
7
+ reset(value?: any): void;
8
+ }
9
+ export declare function createAccessorReactiveObserver(vm: VM, set: (v: any) => void): AccessorReactiveObserver;
@@ -1,4 +1,4 @@
1
- import { ReactiveObserver } from '../libs/mutation-tracker';
1
+ import { ReactiveObserver } from './mutation-tracker';
2
2
  import { VM } from './vm';
3
3
  import { LightningElementConstructor } from './base-lightning-element';
4
4
  import { Template } from './template';
@@ -1,5 +1,3 @@
1
- import { ReactiveObserver } from '../mutation-tracker';
2
- import { VM } from '../vm';
3
1
  /**
4
2
  * @api decorator to mark public fields and public methods in
5
3
  * LWC Components. This function implements the internals of this
@@ -7,10 +5,4 @@ import { VM } from '../vm';
7
5
  */
8
6
  export default function api(target: any, propertyKey: string, descriptor: PropertyDescriptor): void;
9
7
  export declare function createPublicPropertyDescriptor(key: string): PropertyDescriptor;
10
- export declare class AccessorReactiveObserver extends ReactiveObserver {
11
- private value;
12
- private debouncing;
13
- constructor(vm: VM, set: (v: any) => void);
14
- reset(value?: any): void;
15
- }
16
8
  export declare function createPublicAccessorDescriptor(key: PropertyKey, descriptor: PropertyDescriptor): PropertyDescriptor;
@@ -1,9 +1,9 @@
1
- import { ObservableMembrane } from 'observable-membrane';
2
- export declare const lockerLivePropertyKey: unique symbol;
3
- export declare const reactiveMembrane: ObservableMembrane;
4
1
  /**
5
2
  * EXPERIMENTAL: This function implements an unwrap mechanism that
6
3
  * works for observable membrane objects. This API is subject to
7
4
  * change or being removed.
8
5
  */
9
6
  export declare function unwrap(value: any): any;
7
+ export declare function getReadOnlyProxy(value: any): any;
8
+ export declare function getReactiveProxy(value: any): any;
9
+ export declare function markLockerLiveObject(obj: any): void;
@@ -1,4 +1,6 @@
1
+ import { CallbackFunction, ReactiveObserver } from '../libs/mutation-tracker';
1
2
  import { VM } from './vm';
2
3
  export declare function componentValueMutated(vm: VM, key: PropertyKey): void;
3
4
  export declare function componentValueObserved(vm: VM, key: PropertyKey): void;
5
+ export declare function createReactiveObserver(callback: CallbackFunction): ReactiveObserver;
4
6
  export * from '../libs/mutation-tracker';
@@ -3,7 +3,7 @@ import { Template } from './template';
3
3
  import { ComponentDef } from './def';
4
4
  import { LightningElement, LightningElementConstructor } from './base-lightning-element';
5
5
  import { ReactiveObserver } from './mutation-tracker';
6
- import { AccessorReactiveObserver } from './decorators/api';
6
+ import { AccessorReactiveObserver } from './accessor-reactive-observer';
7
7
  import { VNodes, VCustomElement, VNode } from './vnodes';
8
8
  declare type ShadowRootMode = 'open' | 'closed';
9
9
  export interface TemplateCache {
@@ -1,7 +1,7 @@
1
1
  export declare function valueMutated(target: object, key: PropertyKey): void;
2
2
  export declare function valueObserved(target: object, key: PropertyKey): void;
3
- declare type CallbackFunction = (rp: ReactiveObserver) => void;
4
- declare type JobFunction = () => void;
3
+ export declare type CallbackFunction = (rp: ReactiveObserver) => void;
4
+ export declare type JobFunction = () => void;
5
5
  export declare class ReactiveObserver {
6
6
  private listeners;
7
7
  private callback;
@@ -16,4 +16,3 @@ export declare class ReactiveObserver {
16
16
  notify(): void;
17
17
  link(reactiveObservers: ReactiveObserver[]): void;
18
18
  }
19
- export {};