@lwc/engine-core 8.19.0 → 8.20.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.
package/README.md CHANGED
@@ -121,3 +121,18 @@ This experimental API enables the removal of an object's observable membrane pro
121
121
  This experimental API enables the addition of a signal as a trusted signal. If the [ENABLE_EXPERIMENTAL_SIGNALS](https://github.com/salesforce/lwc/blob/master/packages/%40lwc/features/README.md#lwcfeatures) feature is enabled, any signal value change will trigger a re-render.
122
122
 
123
123
  If `setTrustedSignalSet` is called more than once, it will throw an error. If it is never called, then no trusted signal validation will be performed. The same `setTrustedSignalSet` API must be called on both `@lwc/engine-dom` and `@lwc/signals`.
124
+
125
+ ### setContextKeys
126
+
127
+ Not intended for external use. Enables another library to establish contextful relationships via the LWC component tree. The `connectContext` and `disconnectContext` symbols that are provided are later used to identify methods that facilitate the establishment and dissolution of these contextful relationships.
128
+
129
+ ### setTrustedContextSet()
130
+
131
+ Not intended for external use. This experimental API enables the addition of context as trusted context. If the [ENABLE_EXPERIMENTAL_SIGNALS](https://github.com/salesforce/lwc/blob/master/packages/%40lwc/features/README.md#lwcfeatures) feature is enabled.
132
+
133
+ If `setTrustedContextSet` is called more than once, it will throw an error. If it is never called, then context will not be connected.
134
+
135
+ ### ContextBinding
136
+
137
+ The context object's `connectContext` and `disconnectContext` methods are called with this object when contextful components are connected and disconnected. The ContextBinding exposes `provideContext` and `consumeContext`,
138
+ enabling the provision/consumption of a contextful Signal of a specified variety for the associated component.
@@ -28,6 +28,6 @@ export { default as track } from './decorators/track';
28
28
  export { default as wire } from './decorators/wire';
29
29
  export { readonly } from './readonly';
30
30
  export { setFeatureFlag, setFeatureFlagForTest } from '@lwc/features';
31
- export { setTrustedSignalSet } from '@lwc/shared';
31
+ export { setContextKeys, setTrustedSignalSet, setTrustedContextSet } from '@lwc/shared';
32
32
  export type { Stylesheet, Stylesheets } from '@lwc/shared';
33
33
  //# sourceMappingURL=main.d.ts.map
@@ -0,0 +1,4 @@
1
+ import { type VM } from '../vm';
2
+ export declare function connectContext(vm: VM): void;
3
+ export declare function disconnectContext(vm: VM): void;
4
+ //# sourceMappingURL=context.d.ts.map
@@ -1,4 +1,4 @@
1
- import type { WireContextSubscriptionPayload } from './wiring';
1
+ import type { WireContextSubscriptionCallback, WireContextSubscriptionPayload } from './wiring';
2
2
  export type HostNode = any;
3
3
  export type HostElement = any;
4
4
  type N = HostNode;
@@ -47,6 +47,7 @@ export interface RendererAPI {
47
47
  createCustomElement: (tagName: string, upgradeCallback: LifecycleCallback, useNativeLifecycle: boolean, isFormAssociated: boolean) => E;
48
48
  defineCustomElement: (tagName: string, isFormAssociated: boolean) => void;
49
49
  ownerDocument(elm: E): Document;
50
+ registerContextProvider: (element: E, adapterContextToken: string, onContextSubscription: WireContextSubscriptionCallback) => void;
50
51
  registerContextConsumer: (element: E, adapterContextToken: string, subscriptionPayload: WireContextSubscriptionPayload) => void;
51
52
  attachInternals: (elm: E) => ElementInternals;
52
53
  startTrackingMutations: (elm: E) => void;
@@ -35,10 +35,11 @@ export interface WireDebugInfo {
35
35
  context?: ContextValue;
36
36
  wasDataProvisionedForConfig: boolean;
37
37
  }
38
- export type WireContextSubscriptionCallback = (subscriptionPayload: WireContextSubscriptionPayload) => void;
38
+ export type ShouldContinueBubbling = boolean;
39
+ export type WireContextSubscriptionCallback = (subscriptionPayload: WireContextSubscriptionPayload) => ShouldContinueBubbling;
39
40
  export interface WireContextSubscriptionPayload {
40
- setNewContext(newContext: ContextValue): void;
41
- setDisconnectedCallback(disconnectCallback: () => void): void;
41
+ setNewContext(newContext: ContextValue): ShouldContinueBubbling;
42
+ setDisconnectedCallback?(disconnectCallback: () => void): void;
42
43
  }
43
44
  export interface ContextConsumer {
44
45
  provide(newContext: ContextValue): void;
package/dist/index.cjs.js CHANGED
@@ -611,6 +611,7 @@ function componentValueObserved(vm, key, target = {}) {
611
611
  shared.isObject(target) &&
612
612
  !shared.isNull(target) &&
613
613
  shared.isTrustedSignal(target) &&
614
+ process.env.IS_BROWSER &&
614
615
  // Only subscribe if a template is being rendered by the engine
615
616
  tro.isObserving()) {
616
617
  // Subscribe the template reactive observer's notify method, which will mark the vm as dirty and schedule hydration.
@@ -2145,8 +2146,11 @@ function createContextProviderWithRegister(adapter, registerContextProvider) {
2145
2146
  consumerDisconnectedCallback(consumer);
2146
2147
  }
2147
2148
  };
2148
- setDisconnectedCallback(disconnectCallback);
2149
+ setDisconnectedCallback?.(disconnectCallback);
2149
2150
  consumerConnectedCallback(consumer);
2151
+ // Return true as the context is always consumed here and the consumer should
2152
+ // stop bubbling.
2153
+ return true;
2150
2154
  });
2151
2155
  };
2152
2156
  }
@@ -2171,6 +2175,9 @@ function createContextWatcher(vm, wireDef, callbackWhenContextIsReady) {
2171
2175
  // eslint-disable-next-line @lwc/lwc-internal/no-invalid-todo
2172
2176
  // TODO: dev-mode validation of config based on the adapter.contextSchema
2173
2177
  callbackWhenContextIsReady(newContext);
2178
+ // Return true as the context is always consumed here and the consumer should
2179
+ // stop bubbling.
2180
+ return true;
2174
2181
  },
2175
2182
  setDisconnectedCallback(disconnectCallback) {
2176
2183
  // adds this callback into the disconnect bucket so it gets disconnected from parent
@@ -6737,6 +6744,126 @@ function getWrappedComponentsListener(vm, listener) {
6737
6744
  return wrappedListener;
6738
6745
  }
6739
6746
 
6747
+ /******************************************************************************
6748
+ Copyright (c) Microsoft Corporation.
6749
+
6750
+ Permission to use, copy, modify, and/or distribute this software for any
6751
+ purpose with or without fee is hereby granted.
6752
+
6753
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
6754
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
6755
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
6756
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
6757
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
6758
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
6759
+ PERFORMANCE OF THIS SOFTWARE.
6760
+ ***************************************************************************** */
6761
+ /* global Reflect, Promise, SuppressedError, Symbol, Iterator */
6762
+
6763
+
6764
+ function __classPrivateFieldGet(receiver, state, kind, f) {
6765
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
6766
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
6767
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
6768
+ }
6769
+
6770
+ function __classPrivateFieldSet(receiver, state, value, kind, f) {
6771
+ if (kind === "m") throw new TypeError("Private method is not writable");
6772
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
6773
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
6774
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
6775
+ }
6776
+
6777
+ typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
6778
+ var e = new Error(message);
6779
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
6780
+ };
6781
+
6782
+ var _ContextBinding_renderer, _ContextBinding_providedContextVarieties, _ContextBinding_elm;
6783
+ class ContextBinding {
6784
+ constructor(vm, component, providedContextVarieties) {
6785
+ _ContextBinding_renderer.set(this, void 0);
6786
+ _ContextBinding_providedContextVarieties.set(this, void 0);
6787
+ _ContextBinding_elm.set(this, void 0);
6788
+ this.component = component;
6789
+ __classPrivateFieldSet(this, _ContextBinding_renderer, vm.renderer, "f");
6790
+ __classPrivateFieldSet(this, _ContextBinding_elm, vm.elm, "f");
6791
+ __classPrivateFieldSet(this, _ContextBinding_providedContextVarieties, providedContextVarieties, "f");
6792
+ // Register the component as a context provider.
6793
+ __classPrivateFieldGet(this, _ContextBinding_renderer, "f").registerContextProvider(__classPrivateFieldGet(this, _ContextBinding_elm, "f"), shared.ContextEventName, (contextConsumer) => {
6794
+ // This callback is invoked when the provided context is consumed somewhere down
6795
+ // in the component's subtree.
6796
+ return contextConsumer.setNewContext(__classPrivateFieldGet(this, _ContextBinding_providedContextVarieties, "f"));
6797
+ });
6798
+ }
6799
+ provideContext(contextVariety, providedContextSignal) {
6800
+ if (__classPrivateFieldGet(this, _ContextBinding_providedContextVarieties, "f").has(contextVariety)) {
6801
+ logWarnOnce('Multiple contexts of the same variety were provided. Only the first context will be used.');
6802
+ return;
6803
+ }
6804
+ __classPrivateFieldGet(this, _ContextBinding_providedContextVarieties, "f").set(contextVariety, providedContextSignal);
6805
+ }
6806
+ consumeContext(contextVariety, contextProvidedCallback) {
6807
+ __classPrivateFieldGet(this, _ContextBinding_renderer, "f").registerContextConsumer(__classPrivateFieldGet(this, _ContextBinding_elm, "f"), shared.ContextEventName, {
6808
+ setNewContext: (providerContextVarieties) => {
6809
+ // If the provider has the specified context variety, then it is consumed
6810
+ // and true is returned to stop bubbling.
6811
+ if (providerContextVarieties.has(contextVariety)) {
6812
+ contextProvidedCallback(providerContextVarieties.get(contextVariety));
6813
+ return true;
6814
+ }
6815
+ // Return false as context has not been found/consumed
6816
+ // and the consumer should continue traversing the context tree
6817
+ return false;
6818
+ },
6819
+ });
6820
+ }
6821
+ }
6822
+ _ContextBinding_renderer = new WeakMap(), _ContextBinding_providedContextVarieties = new WeakMap(), _ContextBinding_elm = new WeakMap();
6823
+ function connectContext(vm) {
6824
+ const contextKeys = shared.getContextKeys();
6825
+ if (shared.isUndefined(contextKeys)) {
6826
+ return;
6827
+ }
6828
+ const { connectContext } = contextKeys;
6829
+ const { component } = vm;
6830
+ const enumerableKeys = shared.keys(shared.getPrototypeOf(component));
6831
+ const contextfulKeys = shared.ArrayFilter.call(enumerableKeys, (enumerableKey) => shared.isTrustedContext(component[enumerableKey]));
6832
+ if (contextfulKeys.length === 0) {
6833
+ return;
6834
+ }
6835
+ const providedContextVarieties = new Map();
6836
+ try {
6837
+ for (let i = 0; i < contextfulKeys.length; i++) {
6838
+ component[contextfulKeys[i]][connectContext](new ContextBinding(vm, component, providedContextVarieties));
6839
+ }
6840
+ }
6841
+ catch (err) {
6842
+ logWarnOnce(`Attempted to connect to trusted context but received the following error: ${err.message}`);
6843
+ }
6844
+ }
6845
+ function disconnectContext(vm) {
6846
+ const contextKeys = shared.getContextKeys();
6847
+ if (!contextKeys) {
6848
+ return;
6849
+ }
6850
+ const { disconnectContext } = contextKeys;
6851
+ const { component } = vm;
6852
+ const enumerableKeys = shared.keys(shared.getPrototypeOf(component));
6853
+ const contextfulKeys = shared.ArrayFilter.call(enumerableKeys, (enumerableKey) => shared.isTrustedContext(component[enumerableKey]));
6854
+ if (contextfulKeys.length === 0) {
6855
+ return;
6856
+ }
6857
+ try {
6858
+ for (let i = 0; i < contextfulKeys.length; i++) {
6859
+ component[contextfulKeys[i]][disconnectContext](component);
6860
+ }
6861
+ }
6862
+ catch (err) {
6863
+ logWarnOnce(`Attempted to disconnect from trusted context but received the following error: ${err.message}`);
6864
+ }
6865
+ }
6866
+
6740
6867
  /*
6741
6868
  * Copyright (c) 2024, Salesforce, Inc.
6742
6869
  * All rights reserved.
@@ -7120,6 +7247,10 @@ function runConnectedCallback(vm) {
7120
7247
  if (hasWireAdapters(vm)) {
7121
7248
  connectWireAdapters(vm);
7122
7249
  }
7250
+ if (lwcRuntimeFlags.ENABLE_EXPERIMENTAL_SIGNALS) {
7251
+ // Setup context before connected callback is executed
7252
+ connectContext(vm);
7253
+ }
7123
7254
  const { connectedCallback } = vm.def;
7124
7255
  if (!shared.isUndefined(connectedCallback)) {
7125
7256
  logOperationStart(3 /* OperationId.ConnectedCallback */, vm);
@@ -7159,6 +7290,9 @@ function runDisconnectedCallback(vm) {
7159
7290
  if (process.env.NODE_ENV !== 'production') {
7160
7291
  shared.assert.isTrue(vm.state !== 2 /* VMState.disconnected */, `${vm} must be inserted.`);
7161
7292
  }
7293
+ if (lwcRuntimeFlags.ENABLE_EXPERIMENTAL_SIGNALS) {
7294
+ disconnectContext(vm);
7295
+ }
7162
7296
  if (shared.isFalse(vm.isDirty)) {
7163
7297
  // this guarantees that if the component is reused/reinserted,
7164
7298
  // it will be re-rendered because we are disconnecting the reactivity
@@ -8534,10 +8668,18 @@ function readonly(obj) {
8534
8668
  return getReadOnlyProxy(obj);
8535
8669
  }
8536
8670
 
8671
+ Object.defineProperty(exports, "setContextKeys", {
8672
+ enumerable: true,
8673
+ get: function () { return shared.setContextKeys; }
8674
+ });
8537
8675
  Object.defineProperty(exports, "setHooks", {
8538
8676
  enumerable: true,
8539
8677
  get: function () { return shared.setHooks; }
8540
8678
  });
8679
+ Object.defineProperty(exports, "setTrustedContextSet", {
8680
+ enumerable: true,
8681
+ get: function () { return shared.setTrustedContextSet; }
8682
+ });
8541
8683
  Object.defineProperty(exports, "setTrustedSignalSet", {
8542
8684
  enumerable: true,
8543
8685
  get: function () { return shared.setTrustedSignalSet; }
@@ -8586,5 +8728,5 @@ exports.swapTemplate = swapTemplate;
8586
8728
  exports.track = track;
8587
8729
  exports.unwrap = unwrap;
8588
8730
  exports.wire = wire;
8589
- /** version: 8.19.0 */
8731
+ /** version: 8.20.0 */
8590
8732
  //# sourceMappingURL=index.cjs.js.map
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * Copyright (c) 2025 Salesforce, Inc.
3
3
  */
4
- import { noop, StringToLowerCase, isNull, ArrayPush as ArrayPush$1, ArrayJoin, isFrozen, isUndefined as isUndefined$1, defineProperty, seal, create, isAPIFeatureEnabled, isFunction as isFunction$1, keys, toString, isString, ArrayFilter, isObject, isArray as isArray$1, getOwnPropertyNames as getOwnPropertyNames$1, getOwnPropertySymbols as getOwnPropertySymbols$1, ArrayIndexOf, ArrayPop, isFalse, isTrustedSignal, hasOwnProperty as hasOwnProperty$1, entries, AriaPropNameToAttrNameMap, getPropertyDescriptor, AriaAttrNameToPropNameMap, forEach, REFLECTIVE_GLOBAL_PROPERTY_SET, getPrototypeOf as getPrototypeOf$1, setPrototypeOf, defineProperties, assign, freeze, assert, KEY__SYNTHETIC_MODE, getOwnPropertyDescriptor as getOwnPropertyDescriptor$1, LWC_VERSION_COMMENT_REGEX, LWC_VERSION, getOwnPropertyDescriptors, htmlPropertyToAttribute, ArraySlice, ArrayMap, isTrue, KEY__SCOPED_CSS, KEY__NATIVE_ONLY_CSS, ArraySplice, flattenStylesheets, kebabCaseToCamelCase, StringCharCodeAt, XML_NAMESPACE, XLINK_NAMESPACE, StringSlice, SVG_NAMESPACE, KEY__SHADOW_STATIC, ArraySome, KEY__SHADOW_RESOLVER, normalizeClass, sanitizeHtmlContent, StringReplace, isNumber, ArraySort, ArrayFrom, StringCharAt, htmlEscape, LOWEST_API_VERSION, ArrayUnshift, KEY__NATIVE_GET_ELEMENT_BY_ID, KEY__NATIVE_QUERY_SELECTOR_ALL, KEY__SHADOW_TOKEN, ID_REFERENCING_ATTRIBUTES_SET, StringSplit, arrayEvery, parseStyleText, ArrayCopyWithin, ArrayFill, ArrayReverse, ArrayShift } from '@lwc/shared';
5
- export { setHooks, setTrustedSignalSet } from '@lwc/shared';
4
+ import { noop, StringToLowerCase, isNull, ArrayPush as ArrayPush$1, ArrayJoin, isFrozen, isUndefined as isUndefined$1, defineProperty, seal, create, isAPIFeatureEnabled, isFunction as isFunction$1, keys, toString, isString, ArrayFilter, isObject, isArray as isArray$1, getOwnPropertyNames as getOwnPropertyNames$1, getOwnPropertySymbols as getOwnPropertySymbols$1, ArrayIndexOf, ArrayPop, isFalse, isTrustedSignal, hasOwnProperty as hasOwnProperty$1, entries, AriaPropNameToAttrNameMap, getPropertyDescriptor, AriaAttrNameToPropNameMap, forEach, REFLECTIVE_GLOBAL_PROPERTY_SET, getPrototypeOf as getPrototypeOf$1, setPrototypeOf, defineProperties, assign, freeze, assert, KEY__SYNTHETIC_MODE, getOwnPropertyDescriptor as getOwnPropertyDescriptor$1, LWC_VERSION_COMMENT_REGEX, LWC_VERSION, getOwnPropertyDescriptors, htmlPropertyToAttribute, ArraySlice, ArrayMap, isTrue, KEY__SCOPED_CSS, KEY__NATIVE_ONLY_CSS, ArraySplice, flattenStylesheets, kebabCaseToCamelCase, StringCharCodeAt, XML_NAMESPACE, XLINK_NAMESPACE, StringSlice, SVG_NAMESPACE, KEY__SHADOW_STATIC, ArraySome, KEY__SHADOW_RESOLVER, normalizeClass, sanitizeHtmlContent, StringReplace, isNumber, ArraySort, ArrayFrom, StringCharAt, htmlEscape, LOWEST_API_VERSION, getContextKeys, isTrustedContext, ContextEventName, ArrayUnshift, KEY__NATIVE_GET_ELEMENT_BY_ID, KEY__NATIVE_QUERY_SELECTOR_ALL, KEY__SHADOW_TOKEN, ID_REFERENCING_ATTRIBUTES_SET, StringSplit, arrayEvery, parseStyleText, ArrayCopyWithin, ArrayFill, ArrayReverse, ArrayShift } from '@lwc/shared';
5
+ export { setContextKeys, setHooks, setTrustedContextSet, setTrustedSignalSet } from '@lwc/shared';
6
6
  export { setFeatureFlag, setFeatureFlagForTest } from '@lwc/features';
7
7
 
8
8
  /*
@@ -608,6 +608,7 @@ function componentValueObserved(vm, key, target = {}) {
608
608
  isObject(target) &&
609
609
  !isNull(target) &&
610
610
  isTrustedSignal(target) &&
611
+ process.env.IS_BROWSER &&
611
612
  // Only subscribe if a template is being rendered by the engine
612
613
  tro.isObserving()) {
613
614
  // Subscribe the template reactive observer's notify method, which will mark the vm as dirty and schedule hydration.
@@ -2142,8 +2143,11 @@ function createContextProviderWithRegister(adapter, registerContextProvider) {
2142
2143
  consumerDisconnectedCallback(consumer);
2143
2144
  }
2144
2145
  };
2145
- setDisconnectedCallback(disconnectCallback);
2146
+ setDisconnectedCallback?.(disconnectCallback);
2146
2147
  consumerConnectedCallback(consumer);
2148
+ // Return true as the context is always consumed here and the consumer should
2149
+ // stop bubbling.
2150
+ return true;
2147
2151
  });
2148
2152
  };
2149
2153
  }
@@ -2168,6 +2172,9 @@ function createContextWatcher(vm, wireDef, callbackWhenContextIsReady) {
2168
2172
  // eslint-disable-next-line @lwc/lwc-internal/no-invalid-todo
2169
2173
  // TODO: dev-mode validation of config based on the adapter.contextSchema
2170
2174
  callbackWhenContextIsReady(newContext);
2175
+ // Return true as the context is always consumed here and the consumer should
2176
+ // stop bubbling.
2177
+ return true;
2171
2178
  },
2172
2179
  setDisconnectedCallback(disconnectCallback) {
2173
2180
  // adds this callback into the disconnect bucket so it gets disconnected from parent
@@ -6734,6 +6741,126 @@ function getWrappedComponentsListener(vm, listener) {
6734
6741
  return wrappedListener;
6735
6742
  }
6736
6743
 
6744
+ /******************************************************************************
6745
+ Copyright (c) Microsoft Corporation.
6746
+
6747
+ Permission to use, copy, modify, and/or distribute this software for any
6748
+ purpose with or without fee is hereby granted.
6749
+
6750
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
6751
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
6752
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
6753
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
6754
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
6755
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
6756
+ PERFORMANCE OF THIS SOFTWARE.
6757
+ ***************************************************************************** */
6758
+ /* global Reflect, Promise, SuppressedError, Symbol, Iterator */
6759
+
6760
+
6761
+ function __classPrivateFieldGet(receiver, state, kind, f) {
6762
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
6763
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
6764
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
6765
+ }
6766
+
6767
+ function __classPrivateFieldSet(receiver, state, value, kind, f) {
6768
+ if (kind === "m") throw new TypeError("Private method is not writable");
6769
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
6770
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
6771
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
6772
+ }
6773
+
6774
+ typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
6775
+ var e = new Error(message);
6776
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
6777
+ };
6778
+
6779
+ var _ContextBinding_renderer, _ContextBinding_providedContextVarieties, _ContextBinding_elm;
6780
+ class ContextBinding {
6781
+ constructor(vm, component, providedContextVarieties) {
6782
+ _ContextBinding_renderer.set(this, void 0);
6783
+ _ContextBinding_providedContextVarieties.set(this, void 0);
6784
+ _ContextBinding_elm.set(this, void 0);
6785
+ this.component = component;
6786
+ __classPrivateFieldSet(this, _ContextBinding_renderer, vm.renderer, "f");
6787
+ __classPrivateFieldSet(this, _ContextBinding_elm, vm.elm, "f");
6788
+ __classPrivateFieldSet(this, _ContextBinding_providedContextVarieties, providedContextVarieties, "f");
6789
+ // Register the component as a context provider.
6790
+ __classPrivateFieldGet(this, _ContextBinding_renderer, "f").registerContextProvider(__classPrivateFieldGet(this, _ContextBinding_elm, "f"), ContextEventName, (contextConsumer) => {
6791
+ // This callback is invoked when the provided context is consumed somewhere down
6792
+ // in the component's subtree.
6793
+ return contextConsumer.setNewContext(__classPrivateFieldGet(this, _ContextBinding_providedContextVarieties, "f"));
6794
+ });
6795
+ }
6796
+ provideContext(contextVariety, providedContextSignal) {
6797
+ if (__classPrivateFieldGet(this, _ContextBinding_providedContextVarieties, "f").has(contextVariety)) {
6798
+ logWarnOnce('Multiple contexts of the same variety were provided. Only the first context will be used.');
6799
+ return;
6800
+ }
6801
+ __classPrivateFieldGet(this, _ContextBinding_providedContextVarieties, "f").set(contextVariety, providedContextSignal);
6802
+ }
6803
+ consumeContext(contextVariety, contextProvidedCallback) {
6804
+ __classPrivateFieldGet(this, _ContextBinding_renderer, "f").registerContextConsumer(__classPrivateFieldGet(this, _ContextBinding_elm, "f"), ContextEventName, {
6805
+ setNewContext: (providerContextVarieties) => {
6806
+ // If the provider has the specified context variety, then it is consumed
6807
+ // and true is returned to stop bubbling.
6808
+ if (providerContextVarieties.has(contextVariety)) {
6809
+ contextProvidedCallback(providerContextVarieties.get(contextVariety));
6810
+ return true;
6811
+ }
6812
+ // Return false as context has not been found/consumed
6813
+ // and the consumer should continue traversing the context tree
6814
+ return false;
6815
+ },
6816
+ });
6817
+ }
6818
+ }
6819
+ _ContextBinding_renderer = new WeakMap(), _ContextBinding_providedContextVarieties = new WeakMap(), _ContextBinding_elm = new WeakMap();
6820
+ function connectContext(vm) {
6821
+ const contextKeys = getContextKeys();
6822
+ if (isUndefined$1(contextKeys)) {
6823
+ return;
6824
+ }
6825
+ const { connectContext } = contextKeys;
6826
+ const { component } = vm;
6827
+ const enumerableKeys = keys(getPrototypeOf$1(component));
6828
+ const contextfulKeys = ArrayFilter.call(enumerableKeys, (enumerableKey) => isTrustedContext(component[enumerableKey]));
6829
+ if (contextfulKeys.length === 0) {
6830
+ return;
6831
+ }
6832
+ const providedContextVarieties = new Map();
6833
+ try {
6834
+ for (let i = 0; i < contextfulKeys.length; i++) {
6835
+ component[contextfulKeys[i]][connectContext](new ContextBinding(vm, component, providedContextVarieties));
6836
+ }
6837
+ }
6838
+ catch (err) {
6839
+ logWarnOnce(`Attempted to connect to trusted context but received the following error: ${err.message}`);
6840
+ }
6841
+ }
6842
+ function disconnectContext(vm) {
6843
+ const contextKeys = getContextKeys();
6844
+ if (!contextKeys) {
6845
+ return;
6846
+ }
6847
+ const { disconnectContext } = contextKeys;
6848
+ const { component } = vm;
6849
+ const enumerableKeys = keys(getPrototypeOf$1(component));
6850
+ const contextfulKeys = ArrayFilter.call(enumerableKeys, (enumerableKey) => isTrustedContext(component[enumerableKey]));
6851
+ if (contextfulKeys.length === 0) {
6852
+ return;
6853
+ }
6854
+ try {
6855
+ for (let i = 0; i < contextfulKeys.length; i++) {
6856
+ component[contextfulKeys[i]][disconnectContext](component);
6857
+ }
6858
+ }
6859
+ catch (err) {
6860
+ logWarnOnce(`Attempted to disconnect from trusted context but received the following error: ${err.message}`);
6861
+ }
6862
+ }
6863
+
6737
6864
  /*
6738
6865
  * Copyright (c) 2024, Salesforce, Inc.
6739
6866
  * All rights reserved.
@@ -7117,6 +7244,10 @@ function runConnectedCallback(vm) {
7117
7244
  if (hasWireAdapters(vm)) {
7118
7245
  connectWireAdapters(vm);
7119
7246
  }
7247
+ if (lwcRuntimeFlags.ENABLE_EXPERIMENTAL_SIGNALS) {
7248
+ // Setup context before connected callback is executed
7249
+ connectContext(vm);
7250
+ }
7120
7251
  const { connectedCallback } = vm.def;
7121
7252
  if (!isUndefined$1(connectedCallback)) {
7122
7253
  logOperationStart(3 /* OperationId.ConnectedCallback */, vm);
@@ -7156,6 +7287,9 @@ function runDisconnectedCallback(vm) {
7156
7287
  if (process.env.NODE_ENV !== 'production') {
7157
7288
  assert.isTrue(vm.state !== 2 /* VMState.disconnected */, `${vm} must be inserted.`);
7158
7289
  }
7290
+ if (lwcRuntimeFlags.ENABLE_EXPERIMENTAL_SIGNALS) {
7291
+ disconnectContext(vm);
7292
+ }
7159
7293
  if (isFalse(vm.isDirty)) {
7160
7294
  // this guarantees that if the component is reused/reinserted,
7161
7295
  // it will be re-rendered because we are disconnecting the reactivity
@@ -8532,5 +8666,5 @@ function readonly(obj) {
8532
8666
  }
8533
8667
 
8534
8668
  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 };
8535
- /** version: 8.19.0 */
8669
+ /** version: 8.20.0 */
8536
8670
  //# sourceMappingURL=index.js.map
@@ -1,5 +1,6 @@
1
1
  import type { VM } from '../framework/vm';
2
2
  export declare function logError(message: string, vm?: VM): void;
3
+ export declare function logErrorOnce(message: string, vm?: VM): void;
3
4
  export declare function logWarn(message: string, vm?: VM): void;
4
5
  export declare function logWarnOnce(message: string, vm?: VM): void;
5
6
  //# sourceMappingURL=logger.d.ts.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.19.0",
7
+ "version": "8.20.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.19.0",
50
- "@lwc/shared": "8.19.0",
51
- "@lwc/signals": "8.19.0"
49
+ "@lwc/features": "8.20.0",
50
+ "@lwc/shared": "8.20.0",
51
+ "@lwc/signals": "8.20.0"
52
52
  },
53
53
  "devDependencies": {
54
54
  "observable-membrane": "2.0.0"