@lwc/engine-core 7.3.0-alpha.2 → 8.0.0-alpha.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.
@@ -1,9 +1,8 @@
1
- import { LightningElement } from '../base-lightning-element';
2
1
  /**
3
2
  * The `@api` decorator marks public fields and public methods in
4
3
  * LWC Components. This function implements the internals of this
5
4
  * decorator.
6
5
  */
7
- export default function api<Class extends LightningElement>(value: unknown, context: ClassFieldDecoratorContext<Class, unknown> | ClassMethodDecoratorContext<Class, (this: Class, ...args: any) => any> | ClassGetterDecoratorContext<Class, unknown> | ClassSetterDecoratorContext<Class, unknown>): void;
6
+ export default function api(value: unknown, context: ClassMemberDecoratorContext | string | symbol): void;
8
7
  export declare function createPublicPropertyDescriptor(key: string): PropertyDescriptor;
9
8
  export declare function createPublicAccessorDescriptor(key: PropertyKey, descriptor: PropertyDescriptor): PropertyDescriptor;
@@ -1,9 +1,7 @@
1
- import { LightningElement } from '../base-lightning-element';
2
1
  /**
3
2
  * The `@track` decorator function marks field values as reactive in
4
3
  * LWC Components. This function can also be invoked directly
5
4
  * with any value to obtain the trackable version of the value.
6
5
  */
7
- export default function track<Class extends LightningElement>(target: undefined, context: ClassFieldDecoratorContext<Class>): void;
8
- export default function track<T>(target: T, context?: never): T;
6
+ export default function track(value: unknown, context: ClassMemberDecoratorContext | string | symbol): void;
9
7
  export declare function internalTrackDecorator(key: string): PropertyDescriptor;
@@ -1,5 +1,4 @@
1
- import type { LightningElement } from '../base-lightning-element';
2
- import type { ConfigValue, ContextValue, DataCallback, ReplaceReactiveValues, WireAdapterConstructor } from '../wiring';
1
+ import { WireAdapterConstructor } from '../wiring';
3
2
  /**
4
3
  * Decorator factory to wire a property or method to a wire adapter data source.
5
4
  * @param adapter the adapter used to provision data
@@ -11,5 +10,5 @@ import type { ConfigValue, ContextValue, DataCallback, ReplaceReactiveValues, Wi
11
10
  * \@wire(getBook, { id: '$bookId'}) book;
12
11
  * }
13
12
  */
14
- export default function wire<ReactiveConfig extends ConfigValue = ConfigValue, Value = any, Context extends ContextValue = ContextValue, Class extends LightningElement = LightningElement>(adapter: WireAdapterConstructor<ReplaceReactiveValues<ReactiveConfig, Class>, Value, Context>, config?: ReactiveConfig): (target: unknown, context: ClassFieldDecoratorContext<Class, Value | undefined> | ClassMethodDecoratorContext<Class, DataCallback<Value>>) => void;
13
+ export default function wire(adapter: WireAdapterConstructor, config?: Record<string, any>): (value: unknown, context: ClassMemberDecoratorContext | string | symbol) => void;
15
14
  export declare function internalWireFieldDecorator(key: string): PropertyDescriptor;
@@ -0,0 +1,6 @@
1
+ export declare const enum FragmentCacheKey {
2
+ HAS_SCOPED_STYLE = 1,
3
+ SHADOW_MODE_SYNTHETIC = 2
4
+ }
5
+ export declare function getFromFragmentCache(cacheKey: number, strings: string[]): Element | undefined;
6
+ export declare function setInFragmentCache(cacheKey: number, strings: string[], element: Element): void;
@@ -1,3 +1,3 @@
1
1
  export { createContextProviderWithRegister, createContextWatcher } from './context';
2
- export { ConfigCallback, ConfigValue, ContextConsumer, ContextProvider, ContextValue, DataCallback, ReplaceReactiveValues, WireAdapter, WireAdapterConstructor, WireAdapterSchemaValue, WireContextSubscriptionPayload, WireContextSubscriptionCallback, } from './types';
2
+ export { ConfigCallback, ConfigValue, ContextConsumer, ContextProvider, ContextValue, DataCallback, WireAdapter, WireAdapterConstructor, WireAdapterSchemaValue, WireContextSubscriptionPayload, WireContextSubscriptionCallback, } from './types';
3
3
  export { connectWireAdapters, disconnectWireAdapters, installWireAdapters, storeWiredFieldMeta, storeWiredMethodMeta, } from './wiring';
@@ -49,14 +49,3 @@ export interface ContextProviderOptions {
49
49
  }
50
50
  export type ContextProvider = (elmOrComponent: EventTarget, options: ContextProviderOptions) => void;
51
51
  export type RegisterContextProviderFn = (element: HostElement, adapterContextToken: string, onContextSubscription: WireContextSubscriptionCallback) => void;
52
- /** Resolves a property chain to the corresponding value on the target type. */
53
- type ResolveReactiveValue<Target, Keys> = Keys extends keyof Target ? Target[Keys] : Keys extends `${infer K}.${infer Rest}` ? K extends keyof Target ? ResolveReactiveValue<Target[K], Rest> : undefined : undefined;
54
- /**
55
- * Detects if the `Value` type is a property chain starting with "$". If so, it resolves the
56
- * properties to the corresponding value on the target type.
57
- */
58
- type ResolveValueIfReactive<Value, Target> = Value extends string ? string extends Value ? any : Value extends `$${infer Keys}` ? ResolveReactiveValue<Target, Keys> : Value : Value;
59
- export type ReplaceReactiveValues<Config extends ConfigValue, Component extends LightningElement> = {
60
- [K in keyof Config]: ResolveValueIfReactive<Config[K], Component>;
61
- };
62
- export {};
package/dist/index.cjs.js CHANGED
@@ -155,7 +155,7 @@ function log(method, message, vm, once) {
155
155
  }
156
156
  alreadyLoggedMessages.add(msg);
157
157
  }
158
- // In Jest tests, reduce the warning and error verbosity by not printing the callstack
158
+ // In Vitest tests, reduce the warning and error verbosity by not printing the callstack
159
159
  if (process.env.NODE_ENV === 'test') {
160
160
  /* eslint-disable-next-line no-console */
161
161
  console[method](msg);
@@ -1456,7 +1456,7 @@ async function fetchStylesheet(elm) {
1456
1456
  try {
1457
1457
  return await (await fetch(href)).text();
1458
1458
  }
1459
- catch (err) {
1459
+ catch (_err) {
1460
1460
  logWarnOnce(`Ignoring cross-origin stylesheet in migrate mode: ${href}`);
1461
1461
  // ignore errors with cross-origin stylesheets - nothing we can do for those
1462
1462
  return '';
@@ -2378,8 +2378,8 @@ function createPublicAccessorDescriptor(key, descriptor) {
2378
2378
  * SPDX-License-Identifier: MIT
2379
2379
  * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
2380
2380
  */
2381
- function track(target, context) {
2382
- if (shared.isUndefined(context)) {
2381
+ function track(target) {
2382
+ if (arguments.length === 1) {
2383
2383
  return getReactiveProxy(target);
2384
2384
  }
2385
2385
  if (process.env.NODE_ENV !== 'production') {
@@ -5259,22 +5259,30 @@ function s(slotName, data, children, slotset) {
5259
5259
  if (renderMode === 0 /* RenderMode.Light */ &&
5260
5260
  shared.isAPIFeatureEnabled(6 /* APIFeature.USE_LIGHT_DOM_SLOT_FORWARDING */, apiVersion) &&
5261
5261
  (isVBaseElement(vnode) || isVStatic(vnode)) &&
5262
- // We only need to copy the vnodes when the slot assignment changes, copying every time causes issues with
5263
- // disconnected/connected callback firing.
5264
5262
  vnode.slotAssignment !== data.slotAssignment) {
5265
- // When the light DOM slot assignment (slot attribute) changes we can't use the same reference
5266
- // to the vnode because the current way the diffing algo works, it will replace the original reference
5267
- // to the host element with a new one. This means the new element will be mounted and immediately unmounted.
5268
- // Creating a copy of the vnode to preserve a reference to the previous host element.
5269
- if (shared.isUndefined(vnode.elm)) {
5270
- // vnode.elm is undefined during initial render.
5271
- // We don't need to clone at this point because it doesn't need to be unmounted.
5272
- vnode.slotAssignment = data.slotAssignment;
5273
- }
5274
- else {
5275
- // Clone when the vnode.elm is defined to ensure we don't lose reference to the previous element.
5276
- // This is specifically for slot forwarding.
5277
- clonedVNode = { ...vnode, slotAssignment: data.slotAssignment };
5263
+ // When the light DOM slot assignment (slot attribute) changes, we can't use the same reference
5264
+ // to the vnode because the current way the diffing algo works, it will replace the original
5265
+ // reference to the host element with a new one. This means the new element will be mounted and
5266
+ // immediately unmounted. Creating a copy of the vnode preserves a reference to the previous
5267
+ // host element.
5268
+ clonedVNode = { ...vnode, slotAssignment: data.slotAssignment };
5269
+ // For disconnectedCallback to work correctly in synthetic lifecycle mode, we need to link the
5270
+ // current VM's velements to the clone, so that when the VM unmounts, the clone also unmounts.
5271
+ // Note this only applies to VCustomElements, since those are the elements that we manually need
5272
+ // to call disconnectedCallback for, when running in synthetic lifecycle mode.
5273
+ //
5274
+ // You might think it would make more sense to add the clonedVNode to the same velements array
5275
+ // as the original vnode's VM (i.e. `vnode.owner.velements`) rather than the current VM (i.e.
5276
+ // `vmBeingRendered.velements`), but this actually might not trigger disconnectedCallback
5277
+ // in synthetic lifecycle mode. The reason for this is that a reactivity change may cause
5278
+ // the slottable component to unmount, but _not_ the slotter component (see issue #4446).
5279
+ //
5280
+ // If this occurs, then the slottable component (i.e .this component we are rendering right
5281
+ // now) is the one that needs to own the clone. Whereas if a reactivity change higher in the
5282
+ // tree causes the slotter to unmount, then the slottable will also unmount. So using the
5283
+ // current VM works either way.
5284
+ if (isVCustomElement(vnode)) {
5285
+ addVNodeToChildLWC(clonedVNode);
5278
5286
  }
5279
5287
  }
5280
5288
  // If the slot content is standard type, the content is static, no additional
@@ -5796,6 +5804,44 @@ function logGlobalOperationEnd(opId, vm) {
5796
5804
  }
5797
5805
  }
5798
5806
 
5807
+ /*
5808
+ * Copyright (c) 2024, Salesforce, Inc.
5809
+ * All rights reserved.
5810
+ * SPDX-License-Identifier: MIT
5811
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
5812
+ */
5813
+ // HAS_SCOPED_STYLE | SHADOW_MODE_SYNTHETIC = 3
5814
+ const MAX_CACHE_KEY = 3;
5815
+ // Mapping of cacheKeys to `string[]` (assumed to come from a tagged template literal) to an Element.
5816
+ // Note that every unique tagged template literal will have a unique `string[]`. So by using `string[]`
5817
+ // as the WeakMap key, we effectively associate each Element with a unique tagged template literal.
5818
+ // See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#tagged_templates
5819
+ // Also note that this array only needs to be large enough to account for the maximum possible cache key
5820
+ const fragmentCache = shared.ArrayFrom({ length: MAX_CACHE_KEY + 1 }, () => new WeakMap());
5821
+ // Only used in LWC's Karma tests
5822
+ if (process.env.NODE_ENV === 'test-karma-lwc') {
5823
+ window.__lwcResetFragmentCache = () => {
5824
+ for (let i = 0; i < fragmentCache.length; i++) {
5825
+ fragmentCache[i] = new WeakMap();
5826
+ }
5827
+ };
5828
+ }
5829
+ function checkIsBrowser() {
5830
+ // The fragment cache only serves prevent calling innerHTML multiple times which doesn't happen on the server.
5831
+ /* istanbul ignore next */
5832
+ if (!process.env.IS_BROWSER) {
5833
+ throw new Error('The fragment cache is intended to only be used in @lwc/engine-dom, not @lwc/engine-server');
5834
+ }
5835
+ }
5836
+ function getFromFragmentCache(cacheKey, strings) {
5837
+ checkIsBrowser();
5838
+ return fragmentCache[cacheKey].get(strings);
5839
+ }
5840
+ function setInFragmentCache(cacheKey, strings, element) {
5841
+ checkIsBrowser();
5842
+ fragmentCache[cacheKey].set(strings, element);
5843
+ }
5844
+
5799
5845
  /*
5800
5846
  * Copyright (c) 2024, Salesforce, Inc.
5801
5847
  * All rights reserved.
@@ -5939,47 +5985,33 @@ function serializeClassAttribute(part, classToken) {
5939
5985
  const computedClassName = `${classToken} ${shared.keys(classMap).join(' ')}`.trim();
5940
5986
  return computedClassName.length ? ` class="${shared.htmlEscape(computedClassName, true)}"` : '';
5941
5987
  }
5942
- // This should be a no-op outside of LWC's Karma tests, where it's not needed
5943
- let registerFragmentCache = shared.noop;
5944
- // Only used in LWC's Karma tests
5945
- if (process.env.NODE_ENV === 'test-karma-lwc') {
5946
- // Keep track of fragmentCaches, so we can clear them in LWC's Karma tests
5947
- const fragmentCaches = [];
5948
- registerFragmentCache = (fragmentCache) => {
5949
- fragmentCaches.push(fragmentCache);
5950
- };
5951
- window.__lwcResetFragmentCaches = () => {
5952
- for (const fragmentCache of fragmentCaches) {
5953
- for (const key of shared.keys(fragmentCache)) {
5954
- delete fragmentCache[key];
5955
- }
5956
- }
5957
- };
5958
- }
5959
5988
  function buildParseFragmentFn(createFragmentFn) {
5960
- return (strings, ...keys) => {
5961
- const cache = shared.create(null);
5962
- registerFragmentCache(cache);
5963
- return function (parts) {
5989
+ return function parseFragment(strings, ...keys) {
5990
+ return function applyFragmentParts(parts) {
5964
5991
  const { context: { hasScopedStyles, stylesheetToken, legacyStylesheetToken }, shadowMode, renderer, } = getVMBeingRendered();
5965
5992
  const hasStyleToken = !shared.isUndefined(stylesheetToken);
5966
5993
  const isSyntheticShadow = shadowMode === 1 /* ShadowMode.Synthetic */;
5967
5994
  const hasLegacyToken = lwcRuntimeFlags.ENABLE_LEGACY_SCOPE_TOKENS && !shared.isUndefined(legacyStylesheetToken);
5968
5995
  let cacheKey = 0;
5969
5996
  if (hasStyleToken && hasScopedStyles) {
5970
- cacheKey |= 1 /* FragmentCache.HAS_SCOPED_STYLE */;
5997
+ cacheKey |= 1 /* FragmentCacheKey.HAS_SCOPED_STYLE */;
5971
5998
  }
5972
5999
  if (hasStyleToken && isSyntheticShadow) {
5973
- cacheKey |= 2 /* FragmentCache.SHADOW_MODE_SYNTHETIC */;
6000
+ cacheKey |= 2 /* FragmentCacheKey.SHADOW_MODE_SYNTHETIC */;
5974
6001
  }
5975
6002
  // Cache is only here to prevent calling innerHTML multiple times which doesn't happen on the server.
5976
6003
  if (process.env.IS_BROWSER) {
5977
6004
  // Disable this on the server to prevent cache poisoning when expressions are used.
5978
- const cached = cache[cacheKey];
6005
+ const cached = getFromFragmentCache(cacheKey, strings);
5979
6006
  if (!shared.isUndefined(cached)) {
5980
6007
  return cached;
5981
6008
  }
5982
6009
  }
6010
+ // See W-16614556
6011
+ if ((hasStyleToken && !shared.isString(stylesheetToken)) ||
6012
+ (hasLegacyToken && !shared.isString(legacyStylesheetToken))) {
6013
+ throw new Error('stylesheet token must be a string');
6014
+ }
5983
6015
  // If legacy stylesheet tokens are required, then add them to the rendered string
5984
6016
  const stylesheetTokenToRender = stylesheetToken + (hasLegacyToken ? ` ${legacyStylesheetToken}` : '');
5985
6017
  const classToken = hasScopedStyles && hasStyleToken ? ' ' + stylesheetTokenToRender : '';
@@ -6015,8 +6047,12 @@ function buildParseFragmentFn(createFragmentFn) {
6015
6047
  }
6016
6048
  }
6017
6049
  htmlFragment += strings[strings.length - 1];
6018
- cache[cacheKey] = createFragmentFn(htmlFragment, renderer);
6019
- return cache[cacheKey];
6050
+ const element = createFragmentFn(htmlFragment, renderer);
6051
+ // Cache is only here to prevent calling innerHTML multiple times which doesn't happen on the server.
6052
+ if (process.env.IS_BROWSER) {
6053
+ setInFragmentCache(cacheKey, strings, element);
6054
+ }
6055
+ return element;
6020
6056
  };
6021
6057
  };
6022
6058
  }
@@ -7799,7 +7835,13 @@ function setHooks(hooks) {
7799
7835
  * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
7800
7836
  */
7801
7837
  // See @lwc/engine-core/src/framework/template.ts
7802
- const TEMPLATE_PROPS = ['slots', 'stylesheetToken', 'stylesheets', 'renderMode'];
7838
+ const TEMPLATE_PROPS = [
7839
+ 'slots',
7840
+ 'stylesheetToken',
7841
+ 'stylesheets',
7842
+ 'renderMode',
7843
+ 'legacyStylesheetToken',
7844
+ ];
7803
7845
  // Expandos that may be placed on a stylesheet factory function, and which are meaningful to LWC at runtime
7804
7846
  const STYLESHEET_PROPS = [
7805
7847
  // SEE `KEY__SCOPED_CSS` in @lwc/style-compiler
@@ -8092,5 +8134,5 @@ exports.swapTemplate = swapTemplate;
8092
8134
  exports.track = track;
8093
8135
  exports.unwrap = unwrap;
8094
8136
  exports.wire = wire;
8095
- /** version: 7.3.0-alpha.2 */
8137
+ /** version: 7.2.4 */
8096
8138
  //# sourceMappingURL=index.cjs.js.map