@lwc/engine-core 8.22.5 → 8.23.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.
@@ -8,6 +8,7 @@ type ComponentConstructorMetadata = {
8
8
  tmpl: Template;
9
9
  sel: string;
10
10
  apiVersion: APIVersion;
11
+ enableSyntheticElementInternals?: boolean | undefined;
11
12
  };
12
13
  /**
13
14
  * INTERNAL: This function can only be invoked by compiled code. The compiler
@@ -19,6 +20,7 @@ export declare function registerComponent(Ctor: any, metadata: ComponentConstruc
19
20
  export declare function getComponentRegisteredTemplate(Ctor: LightningElementConstructor): Template | undefined;
20
21
  export declare function getComponentRegisteredName(Ctor: LightningElementConstructor): string | undefined;
21
22
  export declare function getComponentAPIVersion(Ctor: LightningElementConstructor): APIVersion;
23
+ export declare function supportsSyntheticElementInternals(Ctor: LightningElementConstructor): boolean;
22
24
  export declare function getTemplateReactiveObserver(vm: VM): ReactiveObserver;
23
25
  export declare function resetTemplateObserverAndUnsubscribe(vm: VM): void;
24
26
  export declare function renderComponent(vm: VM): VNodes;
package/dist/index.cjs.js CHANGED
@@ -540,6 +540,18 @@ function unsubscribeFromSignals(target) {
540
540
  signalTracker.reset();
541
541
  }
542
542
  }
543
+ /**
544
+ * A normalized string representation of an error, because browsers behave differently
545
+ */
546
+ const errorWithStack = (err) => {
547
+ if (typeof err !== 'object' || err === null) {
548
+ return String(err);
549
+ }
550
+ const stack = 'stack' in err ? String(err.stack) : '';
551
+ const message = 'message' in err ? String(err.message) : '';
552
+ const constructor = err.constructor.name;
553
+ return stack.includes(message) ? stack : `${constructor}: ${message}\n${stack}`;
554
+ };
543
555
  /**
544
556
  * This class is used to keep track of the signals associated to a given object.
545
557
  * It is used to prevent the LWC engine from subscribing duplicate callbacks multiple times
@@ -563,7 +575,7 @@ class SignalTracker {
563
575
  }
564
576
  }
565
577
  catch (err) {
566
- logWarnOnce(`Attempted to subscribe to an object that has the shape of a signal but received the following error: ${err?.stack ?? err}`);
578
+ logWarnOnce(`Attempted to subscribe to an object that has the shape of a signal but received the following error: ${errorWithStack(err)}`);
567
579
  }
568
580
  }
569
581
  unsubscribeFromSignals() {
@@ -571,7 +583,7 @@ class SignalTracker {
571
583
  this.signalToUnsubscribeMap.forEach((unsubscribe) => unsubscribe());
572
584
  }
573
585
  catch (err) {
574
- logWarnOnce(`Attempted to call a signal's unsubscribe callback but received the following error: ${err?.stack ?? err}`);
586
+ logWarnOnce(`Attempted to call a signal's unsubscribe callback but received the following error: ${errorWithStack(err)}`);
575
587
  }
576
588
  }
577
589
  reset() {
@@ -1849,16 +1861,35 @@ LightningElement.prototype = {
1849
1861
  },
1850
1862
  attachInternals() {
1851
1863
  const vm = getAssociatedVM(this);
1852
- const { elm, apiVersion, renderer: { attachInternals }, } = vm;
1864
+ const { def: { ctor }, elm, apiVersion, renderer: { attachInternals }, } = vm;
1853
1865
  if (!shared.isAPIFeatureEnabled(7 /* APIFeature.ENABLE_ELEMENT_INTERNALS_AND_FACE */, apiVersion)) {
1854
1866
  throw new Error(`The attachInternals API is only supported in API version 61 and above. ` +
1855
1867
  `The current version is ${apiVersion}. ` +
1856
1868
  `To use this API, update the LWC component API version. https://lwc.dev/guide/versioning`);
1857
1869
  }
1858
- if (vm.shadowMode === 1 /* ShadowMode.Synthetic */) {
1870
+ const internals = attachInternals(elm);
1871
+ if (vm.shadowMode === 1 /* ShadowMode.Synthetic */ && supportsSyntheticElementInternals(ctor)) {
1872
+ const handler = {
1873
+ get(target, prop) {
1874
+ if (prop === 'shadowRoot') {
1875
+ return vm.shadowRoot;
1876
+ }
1877
+ const value = Reflect.get(target, prop);
1878
+ if (typeof value === 'function') {
1879
+ return value.bind(target);
1880
+ }
1881
+ return value;
1882
+ },
1883
+ set(target, prop, value) {
1884
+ return Reflect.set(target, prop, value);
1885
+ },
1886
+ };
1887
+ return new Proxy(internals, handler);
1888
+ }
1889
+ else if (vm.shadowMode === 1 /* ShadowMode.Synthetic */) {
1859
1890
  throw new Error('attachInternals API is not supported in synthetic shadow.');
1860
1891
  }
1861
- return attachInternals(elm);
1892
+ return internals;
1862
1893
  },
1863
1894
  get isConnected() {
1864
1895
  const vm = getAssociatedVM(this);
@@ -6693,6 +6724,9 @@ function getComponentAPIVersion(Ctor) {
6693
6724
  }
6694
6725
  return apiVersion;
6695
6726
  }
6727
+ function supportsSyntheticElementInternals(Ctor) {
6728
+ return registeredComponentMap.get(Ctor)?.enableSyntheticElementInternals || false;
6729
+ }
6696
6730
  function getTemplateReactiveObserver(vm) {
6697
6731
  const reactiveObserver = createReactiveObserver(() => {
6698
6732
  const { isDirty } = vm;
@@ -6833,42 +6867,72 @@ class ContextBinding {
6833
6867
  }
6834
6868
  _ContextBinding_renderer = new WeakMap(), _ContextBinding_providedContextVarieties = new WeakMap(), _ContextBinding_elm = new WeakMap();
6835
6869
  function connectContext(vm) {
6870
+ /**
6871
+ * If ENABLE_LEGACY_CONTEXT_CONNECTION is true, enumerates directly on the component
6872
+ * which can result in the component lifecycle observing properties that are not typically observed.
6873
+ * See PR #5536 for more information.
6874
+ */
6875
+ if (lwcRuntimeFlags.ENABLE_LEGACY_CONTEXT_CONNECTION) {
6876
+ connect(vm, shared.keys(shared.getPrototypeOf(vm.component)), vm.component);
6877
+ }
6878
+ else {
6879
+ // Non-decorated objects
6880
+ connect(vm, shared.keys(vm.cmpFields), vm.cmpFields);
6881
+ // Decorated objects like @api context
6882
+ connect(vm, shared.keys(vm.cmpProps), vm.cmpProps);
6883
+ }
6884
+ }
6885
+ function disconnectContext(vm) {
6886
+ /**
6887
+ * If ENABLE_LEGACY_CONTEXT_CONNECTION is true, enumerates directly on the component
6888
+ * which can result in the component lifecycle observing properties that are not typically observed.
6889
+ * See PR #5536 for more information.
6890
+ */
6891
+ if (lwcRuntimeFlags.ENABLE_LEGACY_CONTEXT_CONNECTION) {
6892
+ connect(vm, shared.keys(shared.getPrototypeOf(vm.component)), vm.component);
6893
+ }
6894
+ else {
6895
+ // Non-decorated objects
6896
+ disconnect(vm, shared.keys(vm.cmpFields), vm.cmpFields);
6897
+ // Decorated objects like @api context
6898
+ disconnect(vm, shared.keys(vm.cmpProps), vm.cmpProps);
6899
+ }
6900
+ }
6901
+ function connect(vm, enumerableKeys, contextContainer) {
6836
6902
  const contextKeys = shared.getContextKeys();
6837
6903
  if (shared.isUndefined(contextKeys)) {
6838
6904
  return;
6839
6905
  }
6840
6906
  const { connectContext } = contextKeys;
6841
6907
  const { component } = vm;
6842
- const enumerableKeys = shared.keys(shared.getPrototypeOf(component));
6843
- const contextfulKeys = shared.ArrayFilter.call(enumerableKeys, (enumerableKey) => shared.isTrustedContext(component[enumerableKey]));
6908
+ const contextfulKeys = shared.ArrayFilter.call(enumerableKeys, (enumerableKey) => shared.isTrustedContext(contextContainer[enumerableKey]));
6844
6909
  if (contextfulKeys.length === 0) {
6845
6910
  return;
6846
6911
  }
6847
6912
  const providedContextVarieties = new Map();
6848
6913
  try {
6849
6914
  for (let i = 0; i < contextfulKeys.length; i++) {
6850
- component[contextfulKeys[i]][connectContext](new ContextBinding(vm, component, providedContextVarieties));
6915
+ contextContainer[contextfulKeys[i]][connectContext](new ContextBinding(vm, component, providedContextVarieties));
6851
6916
  }
6852
6917
  }
6853
6918
  catch (err) {
6854
6919
  logWarnOnce(`Attempted to connect to trusted context but received the following error: ${err.message}`);
6855
6920
  }
6856
6921
  }
6857
- function disconnectContext(vm) {
6922
+ function disconnect(vm, enumerableKeys, contextContainer) {
6858
6923
  const contextKeys = shared.getContextKeys();
6859
6924
  if (!contextKeys) {
6860
6925
  return;
6861
6926
  }
6862
6927
  const { disconnectContext } = contextKeys;
6863
6928
  const { component } = vm;
6864
- const enumerableKeys = shared.keys(shared.getPrototypeOf(component));
6865
- const contextfulKeys = shared.ArrayFilter.call(enumerableKeys, (enumerableKey) => shared.isTrustedContext(component[enumerableKey]));
6929
+ const contextfulKeys = shared.ArrayFilter.call(enumerableKeys, (enumerableKey) => shared.isTrustedContext(contextContainer[enumerableKey]));
6866
6930
  if (contextfulKeys.length === 0) {
6867
6931
  return;
6868
6932
  }
6869
6933
  try {
6870
6934
  for (let i = 0; i < contextfulKeys.length; i++) {
6871
- component[contextfulKeys[i]][disconnectContext](component);
6935
+ contextContainer[contextfulKeys[i]][disconnectContext](component);
6872
6936
  }
6873
6937
  }
6874
6938
  catch (err) {
@@ -7479,8 +7543,10 @@ function forceRehydration(vm) {
7479
7543
  }
7480
7544
  }
7481
7545
  function runFormAssociatedCustomElementCallback(vm, faceCb, args) {
7482
- const { renderMode, shadowMode } = vm;
7483
- if (shadowMode === 1 /* ShadowMode.Synthetic */ && renderMode !== 0 /* RenderMode.Light */) {
7546
+ const { renderMode, shadowMode, def: { ctor }, } = vm;
7547
+ if (shadowMode === 1 /* ShadowMode.Synthetic */ &&
7548
+ renderMode !== 0 /* RenderMode.Light */ &&
7549
+ !supportsSyntheticElementInternals(ctor)) {
7484
7550
  throw new Error('Form associated lifecycle methods are not available in synthetic shadow. Please use native shadow or light DOM.');
7485
7551
  }
7486
7552
  invokeComponentCallback(vm, faceCb, args);
@@ -8759,5 +8825,5 @@ exports.swapTemplate = swapTemplate;
8759
8825
  exports.track = track;
8760
8826
  exports.unwrap = unwrap;
8761
8827
  exports.wire = wire;
8762
- /** version: 8.22.5 */
8828
+ /** version: 8.23.0 */
8763
8829
  //# sourceMappingURL=index.cjs.js.map
package/dist/index.js CHANGED
@@ -537,6 +537,18 @@ function unsubscribeFromSignals(target) {
537
537
  signalTracker.reset();
538
538
  }
539
539
  }
540
+ /**
541
+ * A normalized string representation of an error, because browsers behave differently
542
+ */
543
+ const errorWithStack = (err) => {
544
+ if (typeof err !== 'object' || err === null) {
545
+ return String(err);
546
+ }
547
+ const stack = 'stack' in err ? String(err.stack) : '';
548
+ const message = 'message' in err ? String(err.message) : '';
549
+ const constructor = err.constructor.name;
550
+ return stack.includes(message) ? stack : `${constructor}: ${message}\n${stack}`;
551
+ };
540
552
  /**
541
553
  * This class is used to keep track of the signals associated to a given object.
542
554
  * It is used to prevent the LWC engine from subscribing duplicate callbacks multiple times
@@ -560,7 +572,7 @@ class SignalTracker {
560
572
  }
561
573
  }
562
574
  catch (err) {
563
- logWarnOnce(`Attempted to subscribe to an object that has the shape of a signal but received the following error: ${err?.stack ?? err}`);
575
+ logWarnOnce(`Attempted to subscribe to an object that has the shape of a signal but received the following error: ${errorWithStack(err)}`);
564
576
  }
565
577
  }
566
578
  unsubscribeFromSignals() {
@@ -568,7 +580,7 @@ class SignalTracker {
568
580
  this.signalToUnsubscribeMap.forEach((unsubscribe) => unsubscribe());
569
581
  }
570
582
  catch (err) {
571
- logWarnOnce(`Attempted to call a signal's unsubscribe callback but received the following error: ${err?.stack ?? err}`);
583
+ logWarnOnce(`Attempted to call a signal's unsubscribe callback but received the following error: ${errorWithStack(err)}`);
572
584
  }
573
585
  }
574
586
  reset() {
@@ -1846,16 +1858,35 @@ LightningElement.prototype = {
1846
1858
  },
1847
1859
  attachInternals() {
1848
1860
  const vm = getAssociatedVM(this);
1849
- const { elm, apiVersion, renderer: { attachInternals }, } = vm;
1861
+ const { def: { ctor }, elm, apiVersion, renderer: { attachInternals }, } = vm;
1850
1862
  if (!isAPIFeatureEnabled(7 /* APIFeature.ENABLE_ELEMENT_INTERNALS_AND_FACE */, apiVersion)) {
1851
1863
  throw new Error(`The attachInternals API is only supported in API version 61 and above. ` +
1852
1864
  `The current version is ${apiVersion}. ` +
1853
1865
  `To use this API, update the LWC component API version. https://lwc.dev/guide/versioning`);
1854
1866
  }
1855
- if (vm.shadowMode === 1 /* ShadowMode.Synthetic */) {
1867
+ const internals = attachInternals(elm);
1868
+ if (vm.shadowMode === 1 /* ShadowMode.Synthetic */ && supportsSyntheticElementInternals(ctor)) {
1869
+ const handler = {
1870
+ get(target, prop) {
1871
+ if (prop === 'shadowRoot') {
1872
+ return vm.shadowRoot;
1873
+ }
1874
+ const value = Reflect.get(target, prop);
1875
+ if (typeof value === 'function') {
1876
+ return value.bind(target);
1877
+ }
1878
+ return value;
1879
+ },
1880
+ set(target, prop, value) {
1881
+ return Reflect.set(target, prop, value);
1882
+ },
1883
+ };
1884
+ return new Proxy(internals, handler);
1885
+ }
1886
+ else if (vm.shadowMode === 1 /* ShadowMode.Synthetic */) {
1856
1887
  throw new Error('attachInternals API is not supported in synthetic shadow.');
1857
1888
  }
1858
- return attachInternals(elm);
1889
+ return internals;
1859
1890
  },
1860
1891
  get isConnected() {
1861
1892
  const vm = getAssociatedVM(this);
@@ -6690,6 +6721,9 @@ function getComponentAPIVersion(Ctor) {
6690
6721
  }
6691
6722
  return apiVersion;
6692
6723
  }
6724
+ function supportsSyntheticElementInternals(Ctor) {
6725
+ return registeredComponentMap.get(Ctor)?.enableSyntheticElementInternals || false;
6726
+ }
6693
6727
  function getTemplateReactiveObserver(vm) {
6694
6728
  const reactiveObserver = createReactiveObserver(() => {
6695
6729
  const { isDirty } = vm;
@@ -6830,42 +6864,72 @@ class ContextBinding {
6830
6864
  }
6831
6865
  _ContextBinding_renderer = new WeakMap(), _ContextBinding_providedContextVarieties = new WeakMap(), _ContextBinding_elm = new WeakMap();
6832
6866
  function connectContext(vm) {
6867
+ /**
6868
+ * If ENABLE_LEGACY_CONTEXT_CONNECTION is true, enumerates directly on the component
6869
+ * which can result in the component lifecycle observing properties that are not typically observed.
6870
+ * See PR #5536 for more information.
6871
+ */
6872
+ if (lwcRuntimeFlags.ENABLE_LEGACY_CONTEXT_CONNECTION) {
6873
+ connect(vm, keys(getPrototypeOf$1(vm.component)), vm.component);
6874
+ }
6875
+ else {
6876
+ // Non-decorated objects
6877
+ connect(vm, keys(vm.cmpFields), vm.cmpFields);
6878
+ // Decorated objects like @api context
6879
+ connect(vm, keys(vm.cmpProps), vm.cmpProps);
6880
+ }
6881
+ }
6882
+ function disconnectContext(vm) {
6883
+ /**
6884
+ * If ENABLE_LEGACY_CONTEXT_CONNECTION is true, enumerates directly on the component
6885
+ * which can result in the component lifecycle observing properties that are not typically observed.
6886
+ * See PR #5536 for more information.
6887
+ */
6888
+ if (lwcRuntimeFlags.ENABLE_LEGACY_CONTEXT_CONNECTION) {
6889
+ connect(vm, keys(getPrototypeOf$1(vm.component)), vm.component);
6890
+ }
6891
+ else {
6892
+ // Non-decorated objects
6893
+ disconnect(vm, keys(vm.cmpFields), vm.cmpFields);
6894
+ // Decorated objects like @api context
6895
+ disconnect(vm, keys(vm.cmpProps), vm.cmpProps);
6896
+ }
6897
+ }
6898
+ function connect(vm, enumerableKeys, contextContainer) {
6833
6899
  const contextKeys = getContextKeys();
6834
6900
  if (isUndefined$1(contextKeys)) {
6835
6901
  return;
6836
6902
  }
6837
6903
  const { connectContext } = contextKeys;
6838
6904
  const { component } = vm;
6839
- const enumerableKeys = keys(getPrototypeOf$1(component));
6840
- const contextfulKeys = ArrayFilter.call(enumerableKeys, (enumerableKey) => isTrustedContext(component[enumerableKey]));
6905
+ const contextfulKeys = ArrayFilter.call(enumerableKeys, (enumerableKey) => isTrustedContext(contextContainer[enumerableKey]));
6841
6906
  if (contextfulKeys.length === 0) {
6842
6907
  return;
6843
6908
  }
6844
6909
  const providedContextVarieties = new Map();
6845
6910
  try {
6846
6911
  for (let i = 0; i < contextfulKeys.length; i++) {
6847
- component[contextfulKeys[i]][connectContext](new ContextBinding(vm, component, providedContextVarieties));
6912
+ contextContainer[contextfulKeys[i]][connectContext](new ContextBinding(vm, component, providedContextVarieties));
6848
6913
  }
6849
6914
  }
6850
6915
  catch (err) {
6851
6916
  logWarnOnce(`Attempted to connect to trusted context but received the following error: ${err.message}`);
6852
6917
  }
6853
6918
  }
6854
- function disconnectContext(vm) {
6919
+ function disconnect(vm, enumerableKeys, contextContainer) {
6855
6920
  const contextKeys = getContextKeys();
6856
6921
  if (!contextKeys) {
6857
6922
  return;
6858
6923
  }
6859
6924
  const { disconnectContext } = contextKeys;
6860
6925
  const { component } = vm;
6861
- const enumerableKeys = keys(getPrototypeOf$1(component));
6862
- const contextfulKeys = ArrayFilter.call(enumerableKeys, (enumerableKey) => isTrustedContext(component[enumerableKey]));
6926
+ const contextfulKeys = ArrayFilter.call(enumerableKeys, (enumerableKey) => isTrustedContext(contextContainer[enumerableKey]));
6863
6927
  if (contextfulKeys.length === 0) {
6864
6928
  return;
6865
6929
  }
6866
6930
  try {
6867
6931
  for (let i = 0; i < contextfulKeys.length; i++) {
6868
- component[contextfulKeys[i]][disconnectContext](component);
6932
+ contextContainer[contextfulKeys[i]][disconnectContext](component);
6869
6933
  }
6870
6934
  }
6871
6935
  catch (err) {
@@ -7476,8 +7540,10 @@ function forceRehydration(vm) {
7476
7540
  }
7477
7541
  }
7478
7542
  function runFormAssociatedCustomElementCallback(vm, faceCb, args) {
7479
- const { renderMode, shadowMode } = vm;
7480
- if (shadowMode === 1 /* ShadowMode.Synthetic */ && renderMode !== 0 /* RenderMode.Light */) {
7543
+ const { renderMode, shadowMode, def: { ctor }, } = vm;
7544
+ if (shadowMode === 1 /* ShadowMode.Synthetic */ &&
7545
+ renderMode !== 0 /* RenderMode.Light */ &&
7546
+ !supportsSyntheticElementInternals(ctor)) {
7481
7547
  throw new Error('Form associated lifecycle methods are not available in synthetic shadow. Please use native shadow or light DOM.');
7482
7548
  }
7483
7549
  invokeComponentCallback(vm, faceCb, args);
@@ -8685,5 +8751,5 @@ function readonly(obj) {
8685
8751
  }
8686
8752
 
8687
8753
  export { BaseBridgeElement, LightningElement, profilerControl as __unstable__ProfilerControl, reportingControl as __unstable__ReportingControl, api$1 as api, computeShadowAndRenderMode, connectRootElement, createContextProviderWithRegister, createVM, disconnectRootElement, freezeTemplate, getAssociatedVMIfPresent, getComponentAPIVersion, getComponentConstructor, getComponentDef, getComponentHtmlPrototype, hydrateRoot, isComponentConstructor, parseFragment, parseSVGFragment, readonly, registerComponent, registerDecorators, registerTemplate, runFormAssociatedCallback, runFormDisabledCallback, runFormResetCallback, runFormStateRestoreCallback, sanitizeAttribute, shouldBeFormAssociated, swapComponent, swapStyle, swapTemplate, track, unwrap, wire };
8688
- /** version: 8.22.5 */
8754
+ /** version: 8.23.0 */
8689
8755
  //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "You can safely modify dependencies, devDependencies, keywords, etc., but other props will be overwritten."
5
5
  ],
6
6
  "name": "@lwc/engine-core",
7
- "version": "8.22.5",
7
+ "version": "8.23.0",
8
8
  "description": "Core LWC engine APIs.",
9
9
  "keywords": [
10
10
  "lwc"
@@ -46,9 +46,9 @@
46
46
  }
47
47
  },
48
48
  "dependencies": {
49
- "@lwc/features": "8.22.5",
50
- "@lwc/shared": "8.22.5",
51
- "@lwc/signals": "8.22.5"
49
+ "@lwc/features": "8.23.0",
50
+ "@lwc/shared": "8.23.0",
51
+ "@lwc/signals": "8.23.0"
52
52
  },
53
53
  "devDependencies": {
54
54
  "observable-membrane": "2.0.0"