@lwc/engine-core 8.22.6 → 8.24.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,11 @@ type ComponentConstructorMetadata = {
8
8
  tmpl: Template;
9
9
  sel: string;
10
10
  apiVersion: APIVersion;
11
+ enableSyntheticElementInternals?: boolean | undefined;
12
+ componentFeatureFlag?: {
13
+ value: boolean;
14
+ path: string;
15
+ } | undefined;
11
16
  };
12
17
  /**
13
18
  * INTERNAL: This function can only be invoked by compiled code. The compiler
@@ -19,6 +24,9 @@ export declare function registerComponent(Ctor: any, metadata: ComponentConstruc
19
24
  export declare function getComponentRegisteredTemplate(Ctor: LightningElementConstructor): Template | undefined;
20
25
  export declare function getComponentRegisteredName(Ctor: LightningElementConstructor): string | undefined;
21
26
  export declare function getComponentAPIVersion(Ctor: LightningElementConstructor): APIVersion;
27
+ export declare function supportsSyntheticElementInternals(Ctor: LightningElementConstructor): boolean;
28
+ export declare function isComponentFeatureEnabled(Ctor: LightningElementConstructor): boolean;
29
+ export declare function getComponentMetadata(Ctor: LightningElementConstructor): ComponentConstructorMetadata | undefined;
22
30
  export declare function getTemplateReactiveObserver(vm: VM): ReactiveObserver;
23
31
  export declare function resetTemplateObserverAndUnsubscribe(vm: VM): void;
24
32
  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);
@@ -3723,6 +3754,13 @@ function getCtorProto(Ctor) {
3723
3754
  return proto;
3724
3755
  }
3725
3756
  function createComponentDef(Ctor) {
3757
+ // Enforce component-level feature flag if provided at compile time
3758
+ if (!isComponentFeatureEnabled(Ctor)) {
3759
+ const metadata = getComponentMetadata(Ctor);
3760
+ const componentName = Ctor.name || metadata?.sel || 'Unknown';
3761
+ const componentFeatureFlagPath = metadata?.componentFeatureFlag?.path || 'Unknown';
3762
+ throw new Error(`Component ${componentName} is disabled by the feature flag at ${componentFeatureFlagPath}.`);
3763
+ }
3726
3764
  const { shadowSupportMode: ctorShadowSupportMode, renderMode: ctorRenderMode, formAssociated: ctorFormAssociated, } = Ctor;
3727
3765
  if (process.env.NODE_ENV !== 'production') {
3728
3766
  const ctorName = Ctor.name;
@@ -6693,6 +6731,17 @@ function getComponentAPIVersion(Ctor) {
6693
6731
  }
6694
6732
  return apiVersion;
6695
6733
  }
6734
+ function supportsSyntheticElementInternals(Ctor) {
6735
+ return registeredComponentMap.get(Ctor)?.enableSyntheticElementInternals || false;
6736
+ }
6737
+ function isComponentFeatureEnabled(Ctor) {
6738
+ const flag = registeredComponentMap.get(Ctor)?.componentFeatureFlag;
6739
+ // Default to true if not provided
6740
+ return flag?.value !== false;
6741
+ }
6742
+ function getComponentMetadata(Ctor) {
6743
+ return registeredComponentMap.get(Ctor);
6744
+ }
6696
6745
  function getTemplateReactiveObserver(vm) {
6697
6746
  const reactiveObserver = createReactiveObserver(() => {
6698
6747
  const { isDirty } = vm;
@@ -7509,8 +7558,10 @@ function forceRehydration(vm) {
7509
7558
  }
7510
7559
  }
7511
7560
  function runFormAssociatedCustomElementCallback(vm, faceCb, args) {
7512
- const { renderMode, shadowMode } = vm;
7513
- if (shadowMode === 1 /* ShadowMode.Synthetic */ && renderMode !== 0 /* RenderMode.Light */) {
7561
+ const { renderMode, shadowMode, def: { ctor }, } = vm;
7562
+ if (shadowMode === 1 /* ShadowMode.Synthetic */ &&
7563
+ renderMode !== 0 /* RenderMode.Light */ &&
7564
+ !supportsSyntheticElementInternals(ctor)) {
7514
7565
  throw new Error('Form associated lifecycle methods are not available in synthetic shadow. Please use native shadow or light DOM.');
7515
7566
  }
7516
7567
  invokeComponentCallback(vm, faceCb, args);
@@ -8789,5 +8840,5 @@ exports.swapTemplate = swapTemplate;
8789
8840
  exports.track = track;
8790
8841
  exports.unwrap = unwrap;
8791
8842
  exports.wire = wire;
8792
- /** version: 8.22.6 */
8843
+ /** version: 8.24.0 */
8793
8844
  //# 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);
@@ -3720,6 +3751,13 @@ function getCtorProto(Ctor) {
3720
3751
  return proto;
3721
3752
  }
3722
3753
  function createComponentDef(Ctor) {
3754
+ // Enforce component-level feature flag if provided at compile time
3755
+ if (!isComponentFeatureEnabled(Ctor)) {
3756
+ const metadata = getComponentMetadata(Ctor);
3757
+ const componentName = Ctor.name || metadata?.sel || 'Unknown';
3758
+ const componentFeatureFlagPath = metadata?.componentFeatureFlag?.path || 'Unknown';
3759
+ throw new Error(`Component ${componentName} is disabled by the feature flag at ${componentFeatureFlagPath}.`);
3760
+ }
3723
3761
  const { shadowSupportMode: ctorShadowSupportMode, renderMode: ctorRenderMode, formAssociated: ctorFormAssociated, } = Ctor;
3724
3762
  if (process.env.NODE_ENV !== 'production') {
3725
3763
  const ctorName = Ctor.name;
@@ -6690,6 +6728,17 @@ function getComponentAPIVersion(Ctor) {
6690
6728
  }
6691
6729
  return apiVersion;
6692
6730
  }
6731
+ function supportsSyntheticElementInternals(Ctor) {
6732
+ return registeredComponentMap.get(Ctor)?.enableSyntheticElementInternals || false;
6733
+ }
6734
+ function isComponentFeatureEnabled(Ctor) {
6735
+ const flag = registeredComponentMap.get(Ctor)?.componentFeatureFlag;
6736
+ // Default to true if not provided
6737
+ return flag?.value !== false;
6738
+ }
6739
+ function getComponentMetadata(Ctor) {
6740
+ return registeredComponentMap.get(Ctor);
6741
+ }
6693
6742
  function getTemplateReactiveObserver(vm) {
6694
6743
  const reactiveObserver = createReactiveObserver(() => {
6695
6744
  const { isDirty } = vm;
@@ -7506,8 +7555,10 @@ function forceRehydration(vm) {
7506
7555
  }
7507
7556
  }
7508
7557
  function runFormAssociatedCustomElementCallback(vm, faceCb, args) {
7509
- const { renderMode, shadowMode } = vm;
7510
- if (shadowMode === 1 /* ShadowMode.Synthetic */ && renderMode !== 0 /* RenderMode.Light */) {
7558
+ const { renderMode, shadowMode, def: { ctor }, } = vm;
7559
+ if (shadowMode === 1 /* ShadowMode.Synthetic */ &&
7560
+ renderMode !== 0 /* RenderMode.Light */ &&
7561
+ !supportsSyntheticElementInternals(ctor)) {
7511
7562
  throw new Error('Form associated lifecycle methods are not available in synthetic shadow. Please use native shadow or light DOM.');
7512
7563
  }
7513
7564
  invokeComponentCallback(vm, faceCb, args);
@@ -8715,5 +8766,5 @@ function readonly(obj) {
8715
8766
  }
8716
8767
 
8717
8768
  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 };
8718
- /** version: 8.22.6 */
8769
+ /** version: 8.24.0 */
8719
8770
  //# 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.6",
7
+ "version": "8.24.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.6",
50
- "@lwc/shared": "8.22.6",
51
- "@lwc/signals": "8.22.6"
49
+ "@lwc/features": "8.24.0",
50
+ "@lwc/shared": "8.24.0",
51
+ "@lwc/signals": "8.24.0"
52
52
  },
53
53
  "devDependencies": {
54
54
  "observable-membrane": "2.0.0"