@lwc/engine-core 2.32.0 → 2.32.1

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.
@@ -1,7 +1,7 @@
1
1
  /* proxy-compat-disable */
2
2
  import { lwcRuntimeFlags } from '@lwc/features';
3
3
  export { setFeatureFlag, setFeatureFlagForTest } from '@lwc/features';
4
- import { seal, create, isUndefined as isUndefined$1, isFunction as isFunction$1, ArrayPush as ArrayPush$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, freeze, assert, KEY__SYNTHETIC_MODE, isFalse, isTrue, toString as toString$1, getOwnPropertyDescriptor as getOwnPropertyDescriptor$1, LWC_VERSION_COMMENT_REGEX, LWC_VERSION, htmlPropertyToAttribute, ArraySlice, ArrayMap, isArray as isArray$1, KEY__SCOPED_CSS, StringCharCodeAt, XML_NAMESPACE, XLINK_NAMESPACE, htmlAttributeToProperty, isString, StringSlice, SVG_NAMESPACE, KEY__SHADOW_STATIC, KEY__SHADOW_RESOLVER, ArraySome, isNumber, StringReplace, noop, ArrayUnshift, ArrayFilter, ArrayCopyWithin, ArrayFill, ArraySort, ArrayReverse, ArrayShift, ArrayPop } from '@lwc/shared';
4
+ import { seal, create, isUndefined as isUndefined$1, isFunction as isFunction$1, ArrayPush as ArrayPush$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, freeze, assert, KEY__SYNTHETIC_MODE, toString as toString$1, getOwnPropertyDescriptor as getOwnPropertyDescriptor$1, isFalse, LWC_VERSION_COMMENT_REGEX, LWC_VERSION, htmlPropertyToAttribute, ArraySlice, ArrayMap, isArray as isArray$1, KEY__SCOPED_CSS, StringCharCodeAt, XML_NAMESPACE, XLINK_NAMESPACE, htmlAttributeToProperty, isString, StringSlice, isTrue, SVG_NAMESPACE, KEY__SHADOW_STATIC, KEY__SHADOW_RESOLVER, ArraySome, isNumber, StringReplace, noop, ArrayUnshift, ArrayFilter, ArrayCopyWithin, ArrayFill, ArraySort, ArrayReverse, ArrayShift, ArrayPop } from '@lwc/shared';
5
5
 
6
6
  /*
7
7
  * Copyright (c) 2018, salesforce.com, inc.
@@ -561,7 +561,7 @@ function patchElementWithRestrictions(elm, options) {
561
561
  }),
562
562
  };
563
563
  // Apply extra restriction related to DOM manipulation if the element is not a portal.
564
- if (!options.isLight && !options.isPortal) {
564
+ if (!options.isLight && options.isSynthetic && !options.isPortal) {
565
565
  const { appendChild, insertBefore, removeChild, replaceChild } = elm;
566
566
  const originalNodeValueDescriptor = getPropertyDescriptor(elm, 'nodeValue');
567
567
  const originalInnerHTMLDescriptor = getPropertyDescriptor(elm, 'innerHTML');
@@ -1815,60 +1815,6 @@ function createObservedFieldPropertyDescriptor(key) {
1815
1815
  };
1816
1816
  }
1817
1817
 
1818
- /*
1819
- * Copyright (c) 2018, salesforce.com, inc.
1820
- * All rights reserved.
1821
- * SPDX-License-Identifier: MIT
1822
- * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
1823
- */
1824
- const DUMMY_ACCESSOR_REACTIVE_OBSERVER = {
1825
- observe(job) {
1826
- job();
1827
- },
1828
- reset() { },
1829
- link() { },
1830
- };
1831
- class AccessorReactiveObserver extends ReactiveObserver {
1832
- constructor(vm, set) {
1833
- super(() => {
1834
- if (isFalse(this.debouncing)) {
1835
- this.debouncing = true;
1836
- addCallbackToNextTick(() => {
1837
- if (isTrue(this.debouncing)) {
1838
- const { value } = this;
1839
- const { isDirty: dirtyStateBeforeSetterCall, component, idx } = vm;
1840
- set.call(component, value);
1841
- // de-bouncing after the call to the original setter to prevent
1842
- // infinity loop if the setter itself is mutating things that
1843
- // were accessed during the previous invocation.
1844
- this.debouncing = false;
1845
- if (isTrue(vm.isDirty) && isFalse(dirtyStateBeforeSetterCall) && idx > 0) {
1846
- // immediate rehydration due to a setter driven mutation, otherwise
1847
- // the component will get rendered on the second tick, which it is not
1848
- // desirable.
1849
- rerenderVM(vm);
1850
- }
1851
- }
1852
- });
1853
- }
1854
- });
1855
- this.debouncing = false;
1856
- }
1857
- reset(value) {
1858
- super.reset();
1859
- this.debouncing = false;
1860
- if (arguments.length > 0) {
1861
- this.value = value;
1862
- }
1863
- }
1864
- }
1865
- function createAccessorReactiveObserver(vm, set) {
1866
- // On the server side, we don't need mutation tracking. Skipping it improves performance.
1867
- return process.env.IS_BROWSER
1868
- ? new AccessorReactiveObserver(vm, set)
1869
- : DUMMY_ACCESSOR_REACTIVE_OBSERVER;
1870
- }
1871
-
1872
1818
  /*
1873
1819
  * Copyright (c) 2018, salesforce.com, inc.
1874
1820
  * All rights reserved.
@@ -1876,90 +1822,71 @@ function createAccessorReactiveObserver(vm, set) {
1876
1822
  * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
1877
1823
  */
1878
1824
  function api$1() {
1879
- if (process.env.NODE_ENV !== 'production') {
1880
- assert.fail(`@api decorator can only be used as a decorator function.`);
1881
- }
1882
- throw new Error();
1825
+ if (process.env.NODE_ENV !== 'production') {
1826
+ assert.fail(`@api decorator can only be used as a decorator function.`);
1827
+ }
1828
+ throw new Error();
1883
1829
  }
1884
1830
  function createPublicPropertyDescriptor(key) {
1885
- return {
1886
- get() {
1887
- const vm = getAssociatedVM(this);
1888
- if (isBeingConstructed(vm)) {
1889
- if (process.env.NODE_ENV !== 'production') {
1890
- logError(`Can’t read the value of property \`${toString$1(key)}\` from the constructor because the owner component hasn’t set the value yet. Instead, use the constructor to set a default value for the property.`, vm);
1891
- }
1892
- return;
1893
- }
1894
- componentValueObserved(vm, key);
1895
- return vm.cmpProps[key];
1896
- },
1897
- set(newValue) {
1898
- const vm = getAssociatedVM(this);
1899
- if (process.env.NODE_ENV !== 'production') {
1900
- const vmBeingRendered = getVMBeingRendered();
1901
- assert.invariant(!isInvokingRender, `${vmBeingRendered}.render() method has side effects on the state of ${vm}.${toString$1(key)}`);
1902
- assert.invariant(!isUpdatingTemplate, `Updating the template of ${vmBeingRendered} has side effects on the state of ${vm}.${toString$1(key)}`);
1903
- }
1904
- vm.cmpProps[key] = newValue;
1905
- componentValueMutated(vm, key);
1906
- },
1907
- enumerable: true,
1908
- configurable: true
1909
- };
1831
+ return {
1832
+ get() {
1833
+ const vm = getAssociatedVM(this);
1834
+ if (isBeingConstructed(vm)) {
1835
+ if (process.env.NODE_ENV !== 'production') {
1836
+ logError(`Can’t read the value of property \`${toString$1(key)}\` from the constructor because the owner component hasn’t set the value yet. Instead, use the constructor to set a default value for the property.`, vm);
1837
+ }
1838
+ return;
1839
+ }
1840
+ componentValueObserved(vm, key);
1841
+ return vm.cmpProps[key];
1842
+ },
1843
+ set(newValue) {
1844
+ const vm = getAssociatedVM(this);
1845
+ if (process.env.NODE_ENV !== 'production') {
1846
+ const vmBeingRendered = getVMBeingRendered();
1847
+ assert.invariant(!isInvokingRender, `${vmBeingRendered}.render() method has side effects on the state of ${vm}.${toString$1(key)}`);
1848
+ assert.invariant(!isUpdatingTemplate, `Updating the template of ${vmBeingRendered} has side effects on the state of ${vm}.${toString$1(key)}`);
1849
+ }
1850
+ vm.cmpProps[key] = newValue;
1851
+ componentValueMutated(vm, key);
1852
+ },
1853
+ enumerable: true,
1854
+ configurable: true,
1855
+ };
1910
1856
  }
1911
1857
  function createPublicAccessorDescriptor(key, descriptor) {
1912
- const {
1913
- get,
1914
- set,
1915
- enumerable,
1916
- configurable
1917
- } = descriptor;
1918
- if (!isFunction$1(get)) {
1919
- if (process.env.NODE_ENV !== 'production') {
1920
- assert.invariant(isFunction$1(get), `Invalid compiler output for public accessor ${toString$1(key)} decorated with @api`);
1921
- }
1922
- throw new Error();
1923
- }
1924
- return {
1925
- get() {
1926
- if (process.env.NODE_ENV !== 'production') {
1927
- // Assert that the this value is an actual Component with an associated VM.
1928
- getAssociatedVM(this);
1929
- }
1930
- return get.call(this);
1931
- },
1932
- set(newValue) {
1933
- const vm = getAssociatedVM(this);
1934
- if (process.env.NODE_ENV !== 'production') {
1935
- const vmBeingRendered = getVMBeingRendered();
1936
- assert.invariant(!isInvokingRender, `${vmBeingRendered}.render() method has side effects on the state of ${vm}.${toString$1(key)}`);
1937
- assert.invariant(!isUpdatingTemplate, `Updating the template of ${vmBeingRendered} has side effects on the state of ${vm}.${toString$1(key)}`);
1938
- }
1939
- if (set) {
1940
- if (lwcRuntimeFlags.ENABLE_REACTIVE_SETTER) {
1941
- let ro = vm.oar[key];
1942
- if (isUndefined$1(ro)) {
1943
- ro = vm.oar[key] = createAccessorReactiveObserver(vm, set);
1944
- }
1945
- // every time we invoke this setter from outside (through this wrapper setter)
1946
- // we should reset the value and then debounce just in case there is a pending
1947
- // invocation the next tick that is not longer relevant since the value is changing
1948
- // from outside.
1949
- ro.reset(newValue);
1950
- ro.observe(() => {
1951
- set.call(this, newValue);
1952
- });
1953
- } else {
1954
- set.call(this, newValue);
1858
+ const { get, set, enumerable, configurable } = descriptor;
1859
+ if (!isFunction$1(get)) {
1860
+ if (process.env.NODE_ENV !== 'production') {
1861
+ assert.invariant(isFunction$1(get), `Invalid compiler output for public accessor ${toString$1(key)} decorated with @api`);
1955
1862
  }
1956
- } else if (process.env.NODE_ENV !== 'production') {
1957
- assert.fail(`Invalid attempt to set a new value for property ${toString$1(key)} of ${vm} that does not has a setter decorated with @api.`);
1958
- }
1959
- },
1960
- enumerable,
1961
- configurable
1962
- };
1863
+ throw new Error();
1864
+ }
1865
+ return {
1866
+ get() {
1867
+ if (process.env.NODE_ENV !== 'production') {
1868
+ // Assert that the this value is an actual Component with an associated VM.
1869
+ getAssociatedVM(this);
1870
+ }
1871
+ return get.call(this);
1872
+ },
1873
+ set(newValue) {
1874
+ const vm = getAssociatedVM(this);
1875
+ if (process.env.NODE_ENV !== 'production') {
1876
+ const vmBeingRendered = getVMBeingRendered();
1877
+ assert.invariant(!isInvokingRender, `${vmBeingRendered}.render() method has side effects on the state of ${vm}.${toString$1(key)}`);
1878
+ assert.invariant(!isUpdatingTemplate, `Updating the template of ${vmBeingRendered} has side effects on the state of ${vm}.${toString$1(key)}`);
1879
+ }
1880
+ if (set) {
1881
+ set.call(this, newValue);
1882
+ }
1883
+ else if (process.env.NODE_ENV !== 'production') {
1884
+ assert.fail(`Invalid attempt to set a new value for property ${toString$1(key)} of ${vm} that does not has a setter decorated with @api.`);
1885
+ }
1886
+ },
1887
+ enumerable,
1888
+ configurable,
1889
+ };
1963
1890
  }
1964
1891
 
1965
1892
  /*
@@ -2285,12 +2212,6 @@ function checkVersionMismatch(func, type) {
2285
2212
  }
2286
2213
  }
2287
2214
 
2288
- /*
2289
- * Copyright (c) 2018, salesforce.com, inc.
2290
- * All rights reserved.
2291
- * SPDX-License-Identifier: MIT
2292
- * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
2293
- */
2294
2215
  const signedTemplateSet = new Set();
2295
2216
  function defaultEmptyTemplate() {
2296
2217
  return [];
@@ -2308,32 +2229,6 @@ function registerTemplate(tpl) {
2308
2229
  checkVersionMismatch(tpl, 'template');
2309
2230
  }
2310
2231
  signedTemplateSet.add(tpl);
2311
- // FIXME[@W-10950976]: the template object should be frozen, and it should not be possible to set
2312
- // the stylesheets or stylesheetToken(s). For backwards compat, though, we shim stylesheetTokens
2313
- // on top of stylesheetToken for anyone who is accessing the old internal API.
2314
- // Details: https://salesforce.quip.com/v1rmAFu2cKAr
2315
- defineProperty(tpl, 'stylesheetTokens', {
2316
- enumerable: true,
2317
- configurable: true,
2318
- get() {
2319
- const { stylesheetToken } = this;
2320
- if (isUndefined$1(stylesheetToken)) {
2321
- return stylesheetToken;
2322
- }
2323
- // Shim for the old `stylesheetTokens` property
2324
- // See https://github.com/salesforce/lwc/pull/2332/files#diff-7901555acef29969adaa6583185b3e9bce475cdc6f23e799a54e0018cb18abaa
2325
- return {
2326
- hostAttribute: `${stylesheetToken}-host`,
2327
- shadowAttribute: stylesheetToken,
2328
- };
2329
- },
2330
- set(value) {
2331
- // If the value is null or some other exotic object, you would be broken anyway in the past
2332
- // because the engine would try to access hostAttribute/shadowAttribute, which would throw an error.
2333
- // However it may be undefined in newer versions of LWC, so we need to guard against that case.
2334
- this.stylesheetToken = isUndefined$1(value) ? undefined : value.shadowAttribute;
2335
- },
2336
- });
2337
2232
  // chaining this method as a way to wrap existing
2338
2233
  // assignment of templates easily, without too much transformation
2339
2234
  return tpl;
@@ -3874,11 +3769,13 @@ function applyDomManual(elm, vnode) {
3874
3769
  function applyElementRestrictions(elm, vnode) {
3875
3770
  var _a, _b;
3876
3771
  if (process.env.NODE_ENV !== 'production') {
3772
+ const isSynthetic = vnode.owner.shadowMode === 1 /* ShadowMode.Synthetic */;
3877
3773
  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 */;
3878
3774
  const isLight = vnode.owner.renderMode === 0 /* RenderMode.Light */;
3879
3775
  patchElementWithRestrictions(elm, {
3880
3776
  isPortal,
3881
- isLight
3777
+ isLight,
3778
+ isSynthetic
3882
3779
  });
3883
3780
  }
3884
3781
  }
@@ -4294,7 +4191,7 @@ function s(slotName, data, children, slotset) {
4294
4191
  // undefined is for root components, but root components cannot accept slotted content
4295
4192
  setVMBeingRendered(slotset.owner);
4296
4193
  try {
4297
- ArrayPush$1.apply(newChildren, vnode.factory(data.slotData));
4194
+ ArrayPush$1.call(newChildren, vnode.factory(data.slotData, data.key));
4298
4195
  }
4299
4196
  finally {
4300
4197
  setVMBeingRendered(vmBeingRenderedInception);
@@ -5174,15 +5071,10 @@ function resetComponentStateWhenRemoved(vm) {
5174
5071
  } = vm;
5175
5072
  if (state !== 2 /* VMState.disconnected */) {
5176
5073
  const {
5177
- oar,
5178
5074
  tro
5179
5075
  } = vm;
5180
5076
  // Making sure that any observing record will not trigger the rehydrated on this vm
5181
5077
  tro.reset();
5182
- // Making sure that any observing accessor record will not trigger the setter to be reinvoked
5183
- for (const key in oar) {
5184
- oar[key].reset();
5185
- }
5186
5078
  runDisconnectedCallback(vm);
5187
5079
  // Spec: https://dom.spec.whatwg.org/#concept-node-remove (step 14-15)
5188
5080
  runChildNodesDisconnectedCallback(vm);
@@ -5235,7 +5127,6 @@ function createVM(elm, ctor, renderer, options) {
5235
5127
  cmpSlots: {
5236
5128
  slotAssignments: create(null)
5237
5129
  },
5238
- oar: create(null),
5239
5130
  cmpTemplate: null,
5240
5131
  hydrated: Boolean(hydrated),
5241
5132
  renderMode: def.renderMode,
@@ -6419,94 +6310,166 @@ function setHooks(hooks) {
6419
6310
  // See @lwc/engine-core/src/framework/template.ts
6420
6311
  const TEMPLATE_PROPS = ['slots', 'stylesheetToken', 'stylesheets', 'renderMode'];
6421
6312
  // Via https://www.npmjs.com/package/object-observer
6422
- const ARRAY_MUTATION_METHODS = [
6423
- 'pop',
6424
- 'push',
6425
- 'shift',
6426
- 'unshift',
6427
- 'reverse',
6428
- 'sort',
6429
- 'fill',
6430
- 'splice',
6431
- 'copyWithin',
6432
- ];
6313
+ const ARRAY_MUTATION_METHODS = ['pop', 'push', 'shift', 'unshift', 'reverse', 'sort', 'fill', 'splice', 'copyWithin'];
6314
+ // Expandos that may be placed on a stylesheet factory function, and which are meaningful to LWC at runtime
6315
+ const STYLESHEET_FUNCTION_EXPANDOS = [
6316
+ // SEE `KEY__SCOPED_CSS` in @lwc/style-compiler
6317
+ '$scoped$'];
6433
6318
  function getOriginalArrayMethod(prop) {
6434
- switch (prop) {
6435
- case 'pop':
6436
- return ArrayPop;
6437
- case 'push':
6438
- return ArrayPush$1;
6439
- case 'shift':
6440
- return ArrayShift;
6441
- case 'unshift':
6442
- return ArrayUnshift;
6443
- case 'reverse':
6444
- return ArrayReverse;
6445
- case 'sort':
6446
- return ArraySort;
6447
- case 'fill':
6448
- return ArrayFill;
6449
- case 'splice':
6450
- return ArraySplice;
6451
- case 'copyWithin':
6452
- return ArrayCopyWithin;
6453
- }
6319
+ switch (prop) {
6320
+ case 'pop':
6321
+ return ArrayPop;
6322
+ case 'push':
6323
+ return ArrayPush$1;
6324
+ case 'shift':
6325
+ return ArrayShift;
6326
+ case 'unshift':
6327
+ return ArrayUnshift;
6328
+ case 'reverse':
6329
+ return ArrayReverse;
6330
+ case 'sort':
6331
+ return ArraySort;
6332
+ case 'fill':
6333
+ return ArrayFill;
6334
+ case 'splice':
6335
+ return ArraySplice;
6336
+ case 'copyWithin':
6337
+ return ArrayCopyWithin;
6338
+ }
6454
6339
  }
6455
6340
  let mutationWarningsSilenced = false;
6456
- // Warn if the user tries to mutate tmpl.stylesheets, e.g.:
6341
+ // Warn if the user tries to mutate a stylesheets array, e.g.:
6457
6342
  // `tmpl.stylesheets.push(someStylesheetFunction)`
6458
6343
  function warnOnArrayMutation(stylesheets) {
6459
- // We can't handle users calling Array.prototype.slice.call(tmpl.stylesheets), but
6460
- // we can at least warn when they use the most common mutation methods.
6461
- for (const prop of ARRAY_MUTATION_METHODS) {
6462
- const originalArrayMethod = getOriginalArrayMethod(prop);
6463
- stylesheets[prop] = function arrayMutationWarningWrapper() {
6464
- logError(`Mutating the "stylesheets" array on a template function ` +
6465
- `is deprecated and may be removed in a future version of LWC.`);
6466
- // @ts-ignore
6467
- return originalArrayMethod.apply(this, arguments);
6468
- };
6344
+ // We can't handle users calling Array.prototype.slice.call(tmpl.stylesheets), but
6345
+ // we can at least warn when they use the most common mutation methods.
6346
+ for (const prop of ARRAY_MUTATION_METHODS) {
6347
+ const originalArrayMethod = getOriginalArrayMethod(prop);
6348
+ stylesheets[prop] = function arrayMutationWarningWrapper() {
6349
+ logError(`Mutating the "stylesheets" array on a template function ` + `is deprecated and may be removed in a future version of LWC.`);
6350
+ // @ts-ignore
6351
+ return originalArrayMethod.apply(this, arguments);
6352
+ };
6353
+ }
6354
+ }
6355
+ // Warn if the user tries to mutate a stylesheet factory function, e.g.:
6356
+ // `stylesheet.$scoped$ = true`
6357
+ function warnOnStylesheetFunctionMutation(stylesheet) {
6358
+ // We could warn on other properties, but in practice only certain expandos are meaningful to LWC at runtime
6359
+ for (const prop of STYLESHEET_FUNCTION_EXPANDOS) {
6360
+ let value = stylesheet[prop];
6361
+ defineProperty(stylesheet, prop, {
6362
+ enumerable: true,
6363
+ configurable: true,
6364
+ get() {
6365
+ return value;
6366
+ },
6367
+ set(newValue) {
6368
+ logError(`Dynamically setting the "${prop}" property on a stylesheet function ` + `is deprecated and may be removed in a future version of LWC.`);
6369
+ value = newValue;
6370
+ }
6371
+ });
6372
+ }
6373
+ }
6374
+ // Warn on either array or stylesheet (function) mutation, in a deeply-nested array
6375
+ function warnOnStylesheetsMutation(stylesheets) {
6376
+ traverseStylesheets(stylesheets, subStylesheets => {
6377
+ if (isArray$1(subStylesheets)) {
6378
+ warnOnArrayMutation(subStylesheets);
6379
+ } else {
6380
+ warnOnStylesheetFunctionMutation(subStylesheets);
6469
6381
  }
6382
+ });
6383
+ }
6384
+ // Deeply freeze the entire array (of arrays) of stylesheet factory functions
6385
+ function deepFreeze(stylesheets) {
6386
+ traverseStylesheets(stylesheets, subStylesheets => {
6387
+ freeze(subStylesheets);
6388
+ });
6389
+ }
6390
+ // Deep-traverse an array (of arrays) of stylesheet factory functions, and call the callback for every array/function
6391
+ function traverseStylesheets(stylesheets, callback) {
6392
+ callback(stylesheets);
6393
+ for (let i = 0; i < stylesheets.length; i++) {
6394
+ const stylesheet = stylesheets[i];
6395
+ if (isArray$1(stylesheet)) {
6396
+ traverseStylesheets(stylesheet, callback);
6397
+ } else {
6398
+ callback(stylesheet);
6399
+ }
6400
+ }
6470
6401
  }
6471
- // TODO [#2782]: eventually freezeTemplate() will _actually_ freeze the tmpl object. Today it
6472
- // just warns on mutation.
6473
6402
  function freezeTemplate(tmpl) {
6403
+ if (lwcRuntimeFlags.ENABLE_FROZEN_TEMPLATE) {
6404
+ // Deep freeze the template
6405
+ freeze(tmpl);
6406
+ if (!isUndefined$1(tmpl.stylesheets)) {
6407
+ deepFreeze(tmpl.stylesheets);
6408
+ }
6409
+ } else {
6410
+ // TODO [#2782]: remove this flag and delete the legacy behavior
6411
+ // When ENABLE_FROZEN_TEMPLATE is false, then we shim stylesheetTokens on top of stylesheetToken for anyone who
6412
+ // is accessing the old internal API (backwards compat). Details: https://salesforce.quip.com/v1rmAFu2cKAr
6413
+ defineProperty(tmpl, 'stylesheetTokens', {
6414
+ enumerable: true,
6415
+ configurable: true,
6416
+ get() {
6417
+ const {
6418
+ stylesheetToken
6419
+ } = this;
6420
+ if (isUndefined$1(stylesheetToken)) {
6421
+ return stylesheetToken;
6422
+ }
6423
+ // Shim for the old `stylesheetTokens` property
6424
+ // See https://github.com/salesforce/lwc/pull/2332/files#diff-7901555acef29969adaa6583185b3e9bce475cdc6f23e799a54e0018cb18abaa
6425
+ return {
6426
+ hostAttribute: `${stylesheetToken}-host`,
6427
+ shadowAttribute: stylesheetToken
6428
+ };
6429
+ },
6430
+ set(value) {
6431
+ // If the value is null or some other exotic object, you would be broken anyway in the past
6432
+ // because the engine would try to access hostAttribute/shadowAttribute, which would throw an error.
6433
+ // However it may be undefined in newer versions of LWC, so we need to guard against that case.
6434
+ this.stylesheetToken = isUndefined$1(value) ? undefined : value.shadowAttribute;
6435
+ }
6436
+ });
6437
+ // When ENABLE_FROZEN_TEMPLATE is false, warn in dev mode whenever someone is mutating the template
6474
6438
  if (process.env.NODE_ENV !== 'production') {
6475
- if (!isUndefined$1(tmpl.stylesheets)) {
6476
- warnOnArrayMutation(tmpl.stylesheets);
6477
- }
6478
- for (const prop of TEMPLATE_PROPS) {
6479
- let value = tmpl[prop];
6480
- defineProperty(tmpl, prop, {
6481
- enumerable: true,
6482
- configurable: true,
6483
- get() {
6484
- return value;
6485
- },
6486
- set(newValue) {
6487
- if (!mutationWarningsSilenced) {
6488
- logError(`Dynamically setting the "${prop}" property on a template function ` +
6489
- `is deprecated and may be removed in a future version of LWC.`);
6490
- }
6491
- value = newValue;
6492
- },
6493
- });
6494
- }
6495
- const originalDescriptor = getOwnPropertyDescriptor$1(tmpl, 'stylesheetTokens');
6496
- defineProperty(tmpl, 'stylesheetTokens', {
6497
- enumerable: true,
6498
- configurable: true,
6499
- get: originalDescriptor.get,
6500
- set(value) {
6501
- logError(`Dynamically setting the "stylesheetTokens" property on a template function ` +
6502
- `is deprecated and may be removed in a future version of LWC.`);
6503
- // Avoid logging twice (for both stylesheetToken and stylesheetTokens)
6504
- mutationWarningsSilenced = true;
6505
- originalDescriptor.set.call(this, value);
6506
- mutationWarningsSilenced = false;
6507
- },
6439
+ if (!isUndefined$1(tmpl.stylesheets)) {
6440
+ warnOnStylesheetsMutation(tmpl.stylesheets);
6441
+ }
6442
+ for (const prop of TEMPLATE_PROPS) {
6443
+ let value = tmpl[prop];
6444
+ defineProperty(tmpl, prop, {
6445
+ enumerable: true,
6446
+ configurable: true,
6447
+ get() {
6448
+ return value;
6449
+ },
6450
+ set(newValue) {
6451
+ if (!mutationWarningsSilenced) {
6452
+ logError(`Dynamically setting the "${prop}" property on a template function ` + `is deprecated and may be removed in a future version of LWC.`);
6453
+ }
6454
+ value = newValue;
6455
+ }
6508
6456
  });
6457
+ }
6458
+ const originalDescriptor = getOwnPropertyDescriptor$1(tmpl, 'stylesheetTokens');
6459
+ defineProperty(tmpl, 'stylesheetTokens', {
6460
+ enumerable: true,
6461
+ configurable: true,
6462
+ get: originalDescriptor.get,
6463
+ set(value) {
6464
+ logError(`Dynamically setting the "stylesheetTokens" property on a template function ` + `is deprecated and may be removed in a future version of LWC.`);
6465
+ // Avoid logging twice (for both stylesheetToken and stylesheetTokens)
6466
+ mutationWarningsSilenced = true;
6467
+ originalDescriptor.set.call(this, value);
6468
+ mutationWarningsSilenced = false;
6469
+ }
6470
+ });
6509
6471
  }
6472
+ }
6510
6473
  }
6511
6474
 
6512
6475
  /*
@@ -6533,4 +6496,4 @@ function getComponentConstructor(elm) {
6533
6496
  }
6534
6497
 
6535
6498
  export { LightningElement, profilerControl as __unstable__ProfilerControl, api$1 as api, connectRootElement, createContextProvider, createVM, disconnectRootElement, freezeTemplate, getAssociatedVMIfPresent, getComponentConstructor, getComponentDef, getComponentHtmlPrototype, hydrateRoot, isComponentConstructor, parseFragment, parseSVGFragment, readonly, register, registerComponent, registerDecorators, registerTemplate, sanitizeAttribute, setHooks, swapComponent, swapStyle, swapTemplate, track, unwrap, wire };
6536
- /* version: 2.32.0 */
6499
+ /* version: 2.32.1 */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lwc/engine-core",
3
- "version": "2.32.0",
3
+ "version": "2.32.1",
4
4
  "description": "Core LWC engine APIs.",
5
5
  "homepage": "https://lwc.dev/",
6
6
  "repository": {
@@ -24,8 +24,8 @@
24
24
  "types/"
25
25
  ],
26
26
  "dependencies": {
27
- "@lwc/features": "2.32.0",
28
- "@lwc/shared": "2.32.0"
27
+ "@lwc/features": "2.32.1",
28
+ "@lwc/shared": "2.32.1"
29
29
  },
30
30
  "devDependencies": {
31
31
  "observable-membrane": "2.0.0"
@@ -1,7 +1,7 @@
1
1
  import { SlotSet } from './vm';
2
2
  import { LightningElementConstructor } from './base-lightning-element';
3
3
  import { VNode, VNodes, VElement, VText, VCustomElement, VComment, VElementData, VStatic, Key, VFragment, VScopedSlotFragment } from './vnodes';
4
- declare function ssf(slotName: string, factory: (value: any) => VNodes): VScopedSlotFragment;
4
+ declare function ssf(slotName: string, factory: (value: any, key: any) => VFragment): VScopedSlotFragment;
5
5
  declare function st(fragment: Element, key: Key): VStatic;
6
6
  declare function fr(key: Key, children: VNodes, stable: 0 | 1): VFragment;
7
7
  declare function h(sel: string, data: VElementData, children?: VNodes): VElement;
@@ -24,7 +24,7 @@ declare function fid(url: string | undefined | null): string | null | undefined;
24
24
  * create a dynamic component via `<x-foo lwc:dynamic={Ctor}>`
25
25
  */
26
26
  declare function dc(sel: string, Ctor: LightningElementConstructor | null | undefined, data: VElementData, children?: VNodes): VCustomElement | null;
27
- export declare type SanitizeHtmlContentHook = (content: unknown) => string;
27
+ export type SanitizeHtmlContentHook = (content: unknown) => string;
28
28
  /**
29
29
  * Sets the sanitizeHtmlContentHook.
30
30
  */
@@ -51,4 +51,4 @@ declare const api: Readonly<{
51
51
  ssf: typeof ssf;
52
52
  }>;
53
53
  export default api;
54
- export declare type RenderAPI = typeof api;
54
+ export type RenderAPI = typeof api;
@@ -18,8 +18,8 @@ export interface LightningElementConstructor {
18
18
  renderMode?: 'light' | 'shadow';
19
19
  shadowSupportMode?: ShadowSupportMode;
20
20
  }
21
- declare type HTMLElementTheGoodParts = Pick<Object, 'toString'> & Pick<HTMLElement, 'accessKey' | 'addEventListener' | 'children' | 'childNodes' | 'classList' | 'dir' | 'dispatchEvent' | 'draggable' | 'firstChild' | 'firstElementChild' | 'getAttribute' | 'getAttributeNS' | 'getBoundingClientRect' | 'getElementsByClassName' | 'getElementsByTagName' | 'hasAttribute' | 'hasAttributeNS' | 'hidden' | 'id' | 'isConnected' | 'lang' | 'lastChild' | 'lastElementChild' | 'querySelector' | 'querySelectorAll' | 'removeAttribute' | 'removeAttributeNS' | 'removeEventListener' | 'setAttribute' | 'setAttributeNS' | 'spellcheck' | 'tabIndex' | 'title'>;
22
- declare type RefNodes = {
21
+ type HTMLElementTheGoodParts = Pick<Object, 'toString'> & Pick<HTMLElement, 'accessKey' | 'addEventListener' | 'children' | 'childNodes' | 'classList' | 'dir' | 'dispatchEvent' | 'draggable' | 'firstChild' | 'firstElementChild' | 'getAttribute' | 'getAttributeNS' | 'getBoundingClientRect' | 'getElementsByClassName' | 'getElementsByTagName' | 'hasAttribute' | 'hasAttributeNS' | 'hidden' | 'id' | 'isConnected' | 'lang' | 'lastChild' | 'lastElementChild' | 'querySelector' | 'querySelectorAll' | 'removeAttribute' | 'removeAttributeNS' | 'removeEventListener' | 'setAttribute' | 'setAttributeNS' | 'spellcheck' | 'tabIndex' | 'title'>;
22
+ type RefNodes = {
23
23
  [name: string]: Element;
24
24
  };
25
25
  export interface LightningElement extends HTMLElementTheGoodParts, AccessibleElementProperties {
@@ -1,9 +1,9 @@
1
1
  import { LightningElementConstructor } from '../base-lightning-element';
2
2
  import { WireAdapterConstructor, ConfigCallback } from '../wiring';
3
- declare type WireCompilerMeta = Record<string, WireCompilerDef>;
4
- declare type TrackCompilerMeta = Record<string, 1>;
5
- declare type MethodCompilerMeta = string[];
6
- declare type PropCompilerMeta = Record<string, PropCompilerDef>;
3
+ type WireCompilerMeta = Record<string, WireCompilerDef>;
4
+ type TrackCompilerMeta = Record<string, 1>;
5
+ type MethodCompilerMeta = string[];
6
+ type PropCompilerMeta = Record<string, PropCompilerDef>;
7
7
  export declare const enum PropType {
8
8
  Field = 0,
9
9
  Set = 1,
@@ -43,7 +43,7 @@ interface PropDef {
43
43
  type: PropDefType;
44
44
  attr: string;
45
45
  }
46
- declare type PublicMethod = (...args: any[]) => any;
46
+ type PublicMethod = (...args: any[]) => any;
47
47
  interface PublicComponentDef {
48
48
  name: string;
49
49
  props: Record<string, PropDef>;