@lwc/engine-core 8.12.6 → 8.12.7-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.
Files changed (73) hide show
  1. package/dist/framework/api.d.ts +0 -1
  2. package/dist/framework/attributes.d.ts +1 -0
  3. package/dist/framework/base-bridge-element.d.ts +0 -1
  4. package/dist/framework/base-lightning-element.d.ts +0 -1
  5. package/dist/framework/check-version-mismatch.d.ts +0 -1
  6. package/dist/framework/component.d.ts +0 -1
  7. package/dist/framework/decorators/api.d.ts +0 -1
  8. package/dist/framework/decorators/register.d.ts +0 -1
  9. package/dist/framework/decorators/track.d.ts +0 -1
  10. package/dist/framework/decorators/wire.d.ts +3 -2
  11. package/dist/framework/def.d.ts +0 -1
  12. package/dist/framework/fragment-cache.d.ts +0 -1
  13. package/dist/framework/freeze-template.d.ts +0 -1
  14. package/dist/framework/get-component-constructor.d.ts +0 -1
  15. package/dist/framework/hot-swaps.d.ts +0 -1
  16. package/dist/framework/html-element.d.ts +0 -1
  17. package/dist/framework/html-properties.d.ts +0 -1
  18. package/dist/framework/hydration.d.ts +0 -1
  19. package/dist/framework/invoker.d.ts +1 -3
  20. package/dist/framework/main.d.ts +0 -1
  21. package/dist/framework/membrane.d.ts +0 -1
  22. package/dist/framework/modules/attrs.d.ts +0 -1
  23. package/dist/framework/modules/computed-class-attr.d.ts +0 -1
  24. package/dist/framework/modules/computed-style-attr.d.ts +0 -1
  25. package/dist/framework/modules/events.d.ts +0 -1
  26. package/dist/framework/modules/props.d.ts +0 -1
  27. package/dist/framework/modules/refs.d.ts +0 -1
  28. package/dist/framework/modules/static-class-attr.d.ts +0 -1
  29. package/dist/framework/modules/static-parts.d.ts +0 -1
  30. package/dist/framework/modules/static-style-attr.d.ts +0 -1
  31. package/dist/framework/modules/text.d.ts +0 -1
  32. package/dist/framework/mutation-logger.d.ts +0 -1
  33. package/dist/framework/mutation-tracker.d.ts +0 -1
  34. package/dist/framework/observed-fields.d.ts +0 -1
  35. package/dist/framework/overridable-hooks.d.ts +6 -0
  36. package/dist/framework/profiler.d.ts +3 -5
  37. package/dist/framework/readonly.d.ts +0 -1
  38. package/dist/framework/renderer.d.ts +0 -1
  39. package/dist/framework/rendering.d.ts +0 -1
  40. package/dist/framework/reporting.d.ts +0 -1
  41. package/dist/framework/restrictions.d.ts +0 -1
  42. package/dist/framework/runtime-instrumentation.d.ts +0 -1
  43. package/dist/framework/sanitized-html-content.d.ts +7 -2
  44. package/dist/framework/secure-template.d.ts +0 -1
  45. package/dist/framework/shadow-migration-mode.d.ts +0 -1
  46. package/dist/framework/stylesheet.d.ts +0 -1
  47. package/dist/framework/template.d.ts +0 -1
  48. package/dist/framework/update-component-value.d.ts +0 -1
  49. package/dist/framework/utils.d.ts +0 -2
  50. package/dist/framework/vm.d.ts +0 -1
  51. package/dist/framework/vnodes.d.ts +0 -1
  52. package/dist/framework/weak-multimap.d.ts +0 -1
  53. package/dist/framework/wiring/context.d.ts +0 -1
  54. package/dist/framework/wiring/index.d.ts +0 -1
  55. package/dist/framework/wiring/types.d.ts +0 -1
  56. package/dist/framework/wiring/wiring.d.ts +0 -1
  57. package/dist/index.cjs.js +130 -197
  58. package/dist/index.d.ts +0 -1
  59. package/dist/index.js +130 -197
  60. package/dist/libs/aria-reflection/aria-reflection.d.ts +1 -0
  61. package/dist/libs/aria-reflection/attr-reflection.d.ts +2 -0
  62. package/dist/libs/mutation-tracker/index.d.ts +0 -1
  63. package/dist/libs/reflection/aria-reflection.d.ts +0 -1
  64. package/dist/libs/reflection/attr-reflection.d.ts +0 -1
  65. package/dist/libs/reflection/index.d.ts +0 -1
  66. package/dist/libs/signal-tracker/index.d.ts +0 -1
  67. package/dist/patches/detect-non-standard-aria.d.ts +0 -1
  68. package/dist/patches/detect-synthetic-cross-root-aria.d.ts +0 -1
  69. package/dist/shared/circular-module-dependencies.d.ts +0 -1
  70. package/dist/shared/error.d.ts +0 -1
  71. package/dist/shared/format.d.ts +0 -1
  72. package/dist/shared/logger.d.ts +0 -1
  73. package/package.json +5 -5
package/dist/index.js CHANGED
@@ -248,16 +248,6 @@ function shouldBeFormAssociated(Ctor) {
248
248
  }
249
249
  return ctorFormAssociated && apiFeatureEnabled;
250
250
  }
251
- // check if a property is in an object, and if the object throws an error merely because we are
252
- // checking if the property exists, return false
253
- function safeHasProp(obj, prop) {
254
- try {
255
- return prop in obj;
256
- }
257
- catch (_err) {
258
- return false;
259
- }
260
- }
261
251
 
262
252
  /*
263
253
  * Copyright (c) 2024, Salesforce, Inc.
@@ -598,14 +588,14 @@ function componentValueObserved(vm, key, target = {}) {
598
588
  valueObserved(component, key);
599
589
  }
600
590
  // The portion of reactivity that's exposed to signals is to subscribe a callback to re-render the VM (templates).
601
- // We check the following to ensure re-render is subscribed at the correct time.
591
+ // We check check the following to ensure re-render is subscribed at the correct time.
602
592
  // 1. The template is currently being rendered (there is a template reactive observer)
603
593
  // 2. There was a call to a getter to access the signal (happens during vnode generation)
604
594
  if (lwcRuntimeFlags.ENABLE_EXPERIMENTAL_SIGNALS &&
605
595
  isObject(target) &&
606
596
  !isNull(target) &&
607
- safeHasProp(target, 'value') &&
608
- safeHasProp(target, 'subscribe') &&
597
+ 'value' in target &&
598
+ 'subscribe' in target &&
609
599
  isFunction$1(target.subscribe) &&
610
600
  isTrustedSignal(target) &&
611
601
  // Only subscribe if a template is being rendered by the engine
@@ -2957,10 +2947,7 @@ function HTMLBridgeElementFactory(SuperClass, publicProperties, methods, observe
2957
2947
  const { observedAttributes: superObservedAttributes = [] } = SuperClass;
2958
2948
  const descriptors = create(null);
2959
2949
  // present a hint message so that developers are aware that they have not decorated property with @api
2960
- // Note that we also don't do this in SSR because we cannot sniff for what props are declared on
2961
- // HTMLElementPrototype, and it seems not worth it to have these dev-only warnings there, since
2962
- // an `in` check could mistakenly assume that a prop is declared on a LightningElement prototype.
2963
- if (process.env.NODE_ENV !== 'production' && process.env.IS_BROWSER) {
2950
+ if (process.env.NODE_ENV !== 'production') {
2964
2951
  // TODO [#3761]: enable for components that don't extend from LightningElement
2965
2952
  if (!isUndefined$1(proto) && !isNull(proto) && !hasCustomSuperClass) {
2966
2953
  const nonPublicPropertiesToWarnOn = new Set([
@@ -3977,6 +3964,15 @@ function safelySetProperty(setProperty, elm, key, value) {
3977
3964
  setProperty(elm, key, value);
3978
3965
  }
3979
3966
  }
3967
+ /**
3968
+ * Given two objects (likely either a string or a SanitizedHtmlContent object), return true if their
3969
+ * string values are equivalent.
3970
+ * @param first
3971
+ * @param second
3972
+ */
3973
+ function isSanitizedHtmlContentEqual(first, second) {
3974
+ return unwrapIfNecessary(first) === unwrapIfNecessary(second);
3975
+ }
3980
3976
 
3981
3977
  /*
3982
3978
  * Copyright (c) 2018, salesforce.com, inc.
@@ -5821,9 +5817,8 @@ const operationIdNameMapping = [
5821
5817
  'renderedCallback',
5822
5818
  'disconnectedCallback',
5823
5819
  'errorCallback',
5824
- 'lwc-render',
5825
- 'lwc-rerender',
5826
- 'lwc-ssr-hydrate',
5820
+ 'lwc-hydrate',
5821
+ 'lwc-rehydrate',
5827
5822
  ];
5828
5823
  const operationTooltipMapping = [
5829
5824
  // constructor
@@ -5840,12 +5835,10 @@ const operationTooltipMapping = [
5840
5835
  'component disconnectedCallback()',
5841
5836
  // errorCallback
5842
5837
  'component errorCallback()',
5843
- // lwc-render
5838
+ // lwc-hydrate
5844
5839
  'component first rendered',
5845
- // lwc-rerender
5840
+ // lwc-rehydrate
5846
5841
  'component re-rendered',
5847
- // lwc-ssr-hydrate
5848
- 'component hydrated from server-rendered HTML',
5849
5842
  ];
5850
5843
  // Even if all the browser the engine supports implements the UserTiming API, we need to guard the measure APIs.
5851
5844
  // JSDom (used in Jest) for example doesn't implement the UserTiming APIs.
@@ -5899,14 +5892,13 @@ function getProperties(vm) {
5899
5892
  function getColor(opId) {
5900
5893
  // As of Sept 2024: primary (dark blue), secondary (light blue), tertiary (green)
5901
5894
  switch (opId) {
5902
- // GlobalSsrHydrate, GlobalRender, and Constructor tend to occur at the top level
5903
- case 7 /* OperationId.GlobalRender */:
5904
- case 9 /* OperationId.GlobalSsrHydrate */:
5895
+ // GlobalHydrate and Constructor tend to occur at the top level
5896
+ case 7 /* OperationId.GlobalHydrate */:
5905
5897
  case 0 /* OperationId.Constructor */:
5906
5898
  return 'primary';
5907
- // GlobalRerender also occurs at the top level, but we want to use tertiary (green) because it's easier to
5899
+ // GlobalRehydrate also occurs at the top level, but we want to use tertiary (green) because it's easier to
5908
5900
  // distinguish from primary, and at a glance you should be able to easily tell re-renders from first renders.
5909
- case 8 /* OperationId.GlobalRerender */:
5901
+ case 8 /* OperationId.GlobalRehydrate */:
5910
5902
  return 'tertiary';
5911
5903
  // Everything else (patch/render/callbacks)
5912
5904
  default:
@@ -6111,7 +6103,7 @@ function getVMBeingRendered() {
6111
6103
  function setVMBeingRendered(vm) {
6112
6104
  vmBeingRendered = vm;
6113
6105
  }
6114
- const VALID_SCOPE_TOKEN_REGEX = /^[a-zA-Z0-9\-_]+$/;
6106
+ const VALID_SCOPE_TOKEN_REGEX = /^[a-zA-Z0-9\-_.]+$/;
6115
6107
  // See W-16614556
6116
6108
  // TODO [#2826]: freeze the template object
6117
6109
  function isValidScopeToken(token) {
@@ -6479,10 +6471,7 @@ function invokeComponentConstructor(vm, Ctor) {
6479
6471
  // the "instanceof" operator would not work here since Locker Service provides its own
6480
6472
  // implementation of LightningElement, so we indirectly check if the base constructor is
6481
6473
  // invoked by accessing the component on the vm.
6482
- const isInvalidConstructor = lwcRuntimeFlags.LEGACY_LOCKER_ENABLED
6483
- ? vmBeingConstructed.component !== result
6484
- : !(result instanceof LightningElement);
6485
- if (isInvalidConstructor) {
6474
+ if (vmBeingConstructed.component !== result) {
6486
6475
  throw new TypeError('Invalid component constructor, the class should extend LightningElement.');
6487
6476
  }
6488
6477
  }
@@ -6668,10 +6657,10 @@ function connectRootElement(elm) {
6668
6657
  const vm = getAssociatedVM(elm);
6669
6658
  if (process.env.NODE_ENV !== 'production') {
6670
6659
  // Flush any logs for this VM so that the initial properties from the constructor don't "count"
6671
- // in subsequent re-renders (lwc-rerender). Right now we're at the first render (lwc-hydrate).
6660
+ // in subsequent re-renders (lwc-rehydrate). Right now we're at the first render (lwc-hydrate).
6672
6661
  flushMutationLogsForVM(vm);
6673
6662
  }
6674
- logGlobalOperationStartWithVM(7 /* OperationId.GlobalRender */, vm);
6663
+ logGlobalOperationStartWithVM(7 /* OperationId.GlobalHydrate */, vm);
6675
6664
  // Usually means moving the element from one place to another, which is observable via
6676
6665
  // life-cycle hooks.
6677
6666
  if (vm.state === 1 /* VMState.connected */) {
@@ -6679,7 +6668,7 @@ function connectRootElement(elm) {
6679
6668
  }
6680
6669
  runConnectedCallback(vm);
6681
6670
  rehydrate(vm);
6682
- logGlobalOperationEndWithVM(7 /* OperationId.GlobalRender */, vm);
6671
+ logGlobalOperationEndWithVM(7 /* OperationId.GlobalHydrate */, vm);
6683
6672
  }
6684
6673
  function disconnectRootElement(elm) {
6685
6674
  const vm = getAssociatedVM(elm);
@@ -6988,7 +6977,7 @@ function flushRehydrationQueue() {
6988
6977
  // Gather the logs before rehydration starts so they can be reported at the end of rehydration.
6989
6978
  // Note that we also clear all existing logs at this point so that subsequent re-renders start from a clean slate.
6990
6979
  const mutationLogs = process.env.NODE_ENV === 'production' ? undefined : getAndFlushMutationLogs();
6991
- logGlobalOperationStart(8 /* OperationId.GlobalRerender */);
6980
+ logGlobalOperationStart(8 /* OperationId.GlobalRehydrate */);
6992
6981
  if (process.env.NODE_ENV !== 'production') {
6993
6982
  assert.invariant(rehydrateQueue.length, `If rehydrateQueue was scheduled, it is because there must be at least one VM on this pending queue instead of ${rehydrateQueue}.`);
6994
6983
  }
@@ -7008,13 +6997,13 @@ function flushRehydrationQueue() {
7008
6997
  ArrayUnshift.apply(rehydrateQueue, ArraySlice.call(vms, i + 1));
7009
6998
  }
7010
6999
  // we need to end the measure before throwing.
7011
- logGlobalOperationEnd(8 /* OperationId.GlobalRerender */, mutationLogs);
7000
+ logGlobalOperationEnd(8 /* OperationId.GlobalRehydrate */, mutationLogs);
7012
7001
  // re-throwing the original error will break the current tick, but since the next tick is
7013
7002
  // already scheduled, it should continue patching the rest.
7014
7003
  throw error;
7015
7004
  }
7016
7005
  }
7017
- logGlobalOperationEnd(8 /* OperationId.GlobalRerender */, mutationLogs);
7006
+ logGlobalOperationEnd(8 /* OperationId.GlobalRehydrate */, mutationLogs);
7018
7007
  }
7019
7008
  function runConnectedCallback(vm) {
7020
7009
  const { state } = vm;
@@ -7536,78 +7525,6 @@ if (process.env.IS_BROWSER && isGlobalAriaPolyfillLoaded()) {
7536
7525
  }
7537
7526
  }
7538
7527
 
7539
- /*
7540
- * Copyright (c) 2024, Salesforce, Inc.
7541
- * All rights reserved.
7542
- * SPDX-License-Identifier: MIT
7543
- * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
7544
- */
7545
- // Errors that occured during the hydration process
7546
- let hydrationErrors = [];
7547
- /*
7548
- Prints attributes as null or "value"
7549
- */
7550
- function prettyPrintAttribute(attribute, value) {
7551
- assertNotProd(); // this method should never leak to prod
7552
- return `${attribute}=${isNull(value) || isUndefined$1(value) ? value : `"${value}"`}`;
7553
- }
7554
- /*
7555
- Sorts and stringifies classes
7556
- */
7557
- function prettyPrintClasses(classes) {
7558
- assertNotProd(); // this method should never leak to prod
7559
- const value = JSON.stringify(ArrayJoin.call(ArraySort.call(ArrayFrom(classes)), ' '));
7560
- return `class=${value}`;
7561
- }
7562
- /*
7563
- Hydration errors occur before the source node has been fully hydrated,
7564
- queue them so they can be logged later against the mounted node.
7565
- */
7566
- function queueHydrationError(type, serverRendered, clientExpected) {
7567
- assertNotProd(); // this method should never leak to prod
7568
- ArrayPush$1.call(hydrationErrors, { type, serverRendered, clientExpected });
7569
- }
7570
- /*
7571
- Flushes (logs) any queued errors after the source node has been mounted.
7572
- */
7573
- function flushHydrationErrors(source) {
7574
- assertNotProd(); // this method should never leak to prod
7575
- for (const hydrationError of hydrationErrors) {
7576
- logHydrationWarning(`Hydration ${hydrationError.type} mismatch on:`, source, `\n- rendered on server:`, hydrationError.serverRendered, `\n- expected on client:`, hydrationError.clientExpected || source);
7577
- }
7578
- hydrationErrors = [];
7579
- }
7580
- function isTypeElement(node) {
7581
- const isCorrectType = node?.nodeType === 1 /* EnvNodeTypes.ELEMENT */;
7582
- if (process.env.NODE_ENV !== 'production' && !isCorrectType) {
7583
- queueHydrationError('node', node);
7584
- }
7585
- return isCorrectType;
7586
- }
7587
- function isTypeText(node) {
7588
- const isCorrectType = node?.nodeType === 3 /* EnvNodeTypes.TEXT */;
7589
- if (process.env.NODE_ENV !== 'production' && !isCorrectType) {
7590
- queueHydrationError('node', node);
7591
- }
7592
- return isCorrectType;
7593
- }
7594
- function isTypeComment(node) {
7595
- const isCorrectType = node?.nodeType === 8 /* EnvNodeTypes.COMMENT */;
7596
- if (process.env.NODE_ENV !== 'production' && !isCorrectType) {
7597
- queueHydrationError('node', node);
7598
- }
7599
- return isCorrectType;
7600
- }
7601
- /*
7602
- logger.ts converts all args to a string, losing object referenences and has
7603
- legacy bloat which would have meant more pathing.
7604
- */
7605
- function logHydrationWarning(...args) {
7606
- assertNotProd(); // this method should never leak to prod
7607
- /* eslint-disable-next-line no-console */
7608
- console.warn('[LWC warn:', ...args);
7609
- }
7610
-
7611
7528
  /*
7612
7529
  * Copyright (c) 2022, salesforce.com, inc.
7613
7530
  * All rights reserved.
@@ -7620,20 +7537,11 @@ const EMPTY_SET = new Set();
7620
7537
  let hasMismatch = false;
7621
7538
  function hydrateRoot(vm) {
7622
7539
  hasMismatch = false;
7623
- logGlobalOperationStartWithVM(9 /* OperationId.GlobalSsrHydrate */, vm);
7624
7540
  runConnectedCallback(vm);
7625
7541
  hydrateVM(vm);
7626
- if (process.env.NODE_ENV !== 'production') {
7627
- /*
7628
- Errors are queued as they occur and then logged with the source element once it has been hydrated and mounted to the DOM.
7629
- Means the element in the console matches what is on the page and the highlighting works properly when you hover over the elements in the console.
7630
- */
7631
- flushHydrationErrors(vm.renderRoot);
7632
- if (hasMismatch) {
7633
- logHydrationWarning('Hydration completed with errors.');
7634
- }
7542
+ if (hasMismatch && process.env.NODE_ENV !== 'production') {
7543
+ logWarn('Hydration completed with errors.', vm);
7635
7544
  }
7636
- logGlobalOperationEndWithVM(9 /* OperationId.GlobalSsrHydrate */, vm);
7637
7545
  }
7638
7546
  function hydrateVM(vm) {
7639
7547
  const children = renderComponent(vm);
@@ -7641,9 +7549,7 @@ function hydrateVM(vm) {
7641
7549
  // reset the refs; they will be set during `hydrateChildren`
7642
7550
  resetRefVNodes(vm);
7643
7551
  const { renderRoot: parentNode, renderer: { getFirstChild }, } = vm;
7644
- logOperationStart(2 /* OperationId.Patch */, vm);
7645
7552
  hydrateChildren(getFirstChild(parentNode), children, parentNode, vm, false);
7646
- logOperationEnd(2 /* OperationId.Patch */, vm);
7647
7553
  runRenderedCallback(vm);
7648
7554
  }
7649
7555
  function hydrateNode(node, vnode, renderer) {
@@ -7672,25 +7578,21 @@ function hydrateNode(node, vnode, renderer) {
7672
7578
  hydratedNode = hydrateCustomElement(node, vnode, vnode.data.renderer ?? renderer);
7673
7579
  break;
7674
7580
  }
7675
- if (process.env.NODE_ENV !== 'production') {
7676
- /*
7677
- Errors are queued as they occur and then logged with the source element once it has been hydrated and mounted to the DOM.
7678
- Means the element in the console matches what is on the page and the highlighting works properly when you hover over the elements in the console.
7679
- */
7680
- flushHydrationErrors(hydratedNode);
7681
- }
7682
7581
  return renderer.nextSibling(hydratedNode);
7683
7582
  }
7684
7583
  const NODE_VALUE_PROP = 'nodeValue';
7685
- function validateTextNodeEquality(node, vnode, renderer) {
7584
+ function textNodeContentsAreEqual(node, vnode, renderer) {
7686
7585
  const { getProperty } = renderer;
7687
7586
  const nodeValue = getProperty(node, NODE_VALUE_PROP);
7688
- if (nodeValue !== vnode.text &&
7689
- // Special case for empty text nodes – these are serialized differently on the server
7690
- // See https://github.com/salesforce/lwc/pull/2656
7691
- (nodeValue !== '\u200D' || vnode.text !== '')) {
7692
- queueHydrationError('text content', nodeValue, vnode.text);
7587
+ if (nodeValue === vnode.text) {
7588
+ return true;
7589
+ }
7590
+ // Special case for empty text nodes these are serialized differently on the server
7591
+ // See https://github.com/salesforce/lwc/pull/2656
7592
+ if (nodeValue === '\u200D' && vnode.text === '') {
7593
+ return true;
7693
7594
  }
7595
+ return false;
7694
7596
  }
7695
7597
  // The validationOptOut static property can be an array of attribute names.
7696
7598
  // Any attribute names specified in that array will not be validated, and the
@@ -7713,7 +7615,7 @@ function getValidationPredicate(elm, renderer, optOutStaticProp) {
7713
7615
  !isUndefined$1(optOutStaticProp) &&
7714
7616
  !isTrue(optOutStaticProp) &&
7715
7617
  !isValidArray) {
7716
- logHydrationWarning('`validationOptOut` must be `true` or an array of attributes that should not be validated.');
7618
+ logWarn('`validationOptOut` must be `true` or an array of attributes that should not be validated.');
7717
7619
  }
7718
7620
  return (attrName) => {
7719
7621
  // Component wants to opt out of all validation
@@ -7733,14 +7635,16 @@ function getValidationPredicate(elm, renderer, optOutStaticProp) {
7733
7635
  };
7734
7636
  }
7735
7637
  function hydrateText(node, vnode, renderer) {
7736
- if (!isTypeText(node)) {
7638
+ if (!hasCorrectNodeType(vnode, node, 3 /* EnvNodeTypes.TEXT */, renderer)) {
7737
7639
  return handleMismatch(node, vnode, renderer);
7738
7640
  }
7739
- return updateTextContent(node, vnode, renderer);
7641
+ return updateTextContent(node, vnode, vnode.owner, renderer);
7740
7642
  }
7741
- function updateTextContent(node, vnode, renderer) {
7643
+ function updateTextContent(node, vnode, owner, renderer) {
7742
7644
  if (process.env.NODE_ENV !== 'production') {
7743
- validateTextNodeEquality(node, vnode, renderer);
7645
+ if (!textNodeContentsAreEqual(node, vnode, renderer)) {
7646
+ logWarn('Hydration mismatch: text values do not match, will recover from the difference', owner);
7647
+ }
7744
7648
  }
7745
7649
  const { setText } = renderer;
7746
7650
  setText(node, vnode.text ?? null);
@@ -7748,14 +7652,14 @@ function updateTextContent(node, vnode, renderer) {
7748
7652
  return node;
7749
7653
  }
7750
7654
  function hydrateComment(node, vnode, renderer) {
7751
- if (!isTypeComment(node)) {
7655
+ if (!hasCorrectNodeType(vnode, node, 8 /* EnvNodeTypes.COMMENT */, renderer)) {
7752
7656
  return handleMismatch(node, vnode, renderer);
7753
7657
  }
7754
7658
  if (process.env.NODE_ENV !== 'production') {
7755
7659
  const { getProperty } = renderer;
7756
7660
  const nodeValue = getProperty(node, NODE_VALUE_PROP);
7757
7661
  if (nodeValue !== vnode.text) {
7758
- queueHydrationError('comment', nodeValue, vnode.text);
7662
+ logWarn('Hydration mismatch: comment values do not match, will recover from the difference', vnode.owner);
7759
7663
  }
7760
7664
  }
7761
7665
  const { setProperty } = renderer;
@@ -7766,12 +7670,11 @@ function hydrateComment(node, vnode, renderer) {
7766
7670
  return node;
7767
7671
  }
7768
7672
  function hydrateStaticElement(elm, vnode, renderer) {
7769
- if (isTypeElement(elm) &&
7770
- isTypeElement(vnode.fragment) &&
7771
- areStaticElementsCompatible(vnode.fragment, elm, vnode, renderer)) {
7772
- return hydrateStaticElementParts(elm, vnode, renderer);
7673
+ if (!hasCorrectNodeType(vnode, elm, 1 /* EnvNodeTypes.ELEMENT */, renderer) ||
7674
+ !areCompatibleStaticNodes(vnode.fragment, elm, vnode, renderer)) {
7675
+ return handleMismatch(elm, vnode, renderer);
7773
7676
  }
7774
- return handleMismatch(elm, vnode, renderer);
7677
+ return hydrateStaticElementParts(elm, vnode, renderer);
7775
7678
  }
7776
7679
  function hydrateStaticElementParts(elm, vnode, renderer) {
7777
7680
  const { parts } = vnode;
@@ -7794,7 +7697,8 @@ function hydrateFragment(elm, vnode, renderer) {
7794
7697
  return (vnode.elm = children[children.length - 1].elm);
7795
7698
  }
7796
7699
  function hydrateElement(elm, vnode, renderer) {
7797
- if (!isTypeElement(elm) || !isMatchingElement(vnode, elm, renderer)) {
7700
+ if (!hasCorrectNodeType(vnode, elm, 1 /* EnvNodeTypes.ELEMENT */, renderer) ||
7701
+ !isMatchingElement(vnode, elm, renderer)) {
7798
7702
  return handleMismatch(elm, vnode, renderer);
7799
7703
  }
7800
7704
  vnode.elm = elm;
@@ -7807,17 +7711,17 @@ function hydrateElement(elm, vnode, renderer) {
7807
7711
  const { data: { props }, } = vnode;
7808
7712
  const { getProperty } = renderer;
7809
7713
  if (!isUndefined$1(props) && !isUndefined$1(props.innerHTML)) {
7810
- const unwrappedServerInnerHTML = unwrapIfNecessary(getProperty(elm, 'innerHTML'));
7811
- const unwrappedClientInnerHTML = unwrapIfNecessary(props.innerHTML);
7812
- if (unwrappedServerInnerHTML === unwrappedClientInnerHTML) {
7714
+ if (isSanitizedHtmlContentEqual(getProperty(elm, 'innerHTML'), props.innerHTML)) {
7813
7715
  // Do a shallow clone since VNodeData may be shared across VNodes due to hoist optimization
7814
7716
  vnode.data = {
7815
7717
  ...vnode.data,
7816
7718
  props: cloneAndOmitKey(props, 'innerHTML'),
7817
7719
  };
7818
7720
  }
7819
- else if (process.env.NODE_ENV !== 'production') {
7820
- queueHydrationError('innerHTML', unwrappedServerInnerHTML, unwrappedClientInnerHTML);
7721
+ else {
7722
+ if (process.env.NODE_ENV !== 'production') {
7723
+ logWarn(`Mismatch hydrating element <${getProperty(elm, 'tagName').toLowerCase()}>: innerHTML values do not match for element, will recover from the difference`, owner);
7724
+ }
7821
7725
  }
7822
7726
  }
7823
7727
  }
@@ -7840,7 +7744,8 @@ function hydrateCustomElement(elm, vnode, renderer) {
7840
7744
  //
7841
7745
  // Therefore, if validationOptOut is falsey or an array of strings, we need to
7842
7746
  // examine some or all of the custom element's attributes.
7843
- if (!isTypeElement(elm) || !isMatchingElement(vnode, elm, renderer, shouldValidateAttr)) {
7747
+ if (!hasCorrectNodeType(vnode, elm, 1 /* EnvNodeTypes.ELEMENT */, renderer) ||
7748
+ !isMatchingElement(vnode, elm, renderer, shouldValidateAttr)) {
7844
7749
  return handleMismatch(elm, vnode, renderer);
7845
7750
  }
7846
7751
  const { sel, mode, ctor, owner } = vnode;
@@ -7876,13 +7781,9 @@ function hydrateChildren(node, children, parentNode, owner,
7876
7781
  // last node of the fragment. Hydration should not fail if a trailing sibling is
7877
7782
  // found in this case.
7878
7783
  expectAddlSiblings) {
7879
- let mismatchedChildren = false;
7784
+ let hasWarned = false;
7880
7785
  let nextNode = node;
7881
7786
  const { renderer } = owner;
7882
- const { getChildNodes, cloneNode } = renderer;
7883
- const serverNodes = process.env.NODE_ENV !== 'production'
7884
- ? Array.from(getChildNodes(parentNode), (node) => cloneNode(node, true))
7885
- : null;
7886
7787
  for (let i = 0; i < children.length; i++) {
7887
7788
  const childVnode = children[i];
7888
7789
  if (!isNull(childVnode)) {
@@ -7890,7 +7791,13 @@ expectAddlSiblings) {
7890
7791
  nextNode = hydrateNode(nextNode, childVnode, renderer);
7891
7792
  }
7892
7793
  else {
7893
- mismatchedChildren = true;
7794
+ hasMismatch = true;
7795
+ if (process.env.NODE_ENV !== 'production') {
7796
+ if (!hasWarned) {
7797
+ hasWarned = true;
7798
+ logWarn(`Hydration mismatch: incorrect number of rendered nodes. Client produced more nodes than the server.`, owner);
7799
+ }
7800
+ }
7894
7801
  mount(childVnode, parentNode, renderer, nextNode);
7895
7802
  nextNode = renderer.nextSibling(childVnode.type === 5 /* VNodeType.Fragment */ ? childVnode.trailing : childVnode.elm);
7896
7803
  }
@@ -7907,7 +7814,12 @@ expectAddlSiblings) {
7907
7814
  // rendered more nodes than the client.
7908
7815
  (!useCommentsForBookends || !expectAddlSiblings) &&
7909
7816
  nextNode) {
7910
- mismatchedChildren = true;
7817
+ hasMismatch = true;
7818
+ if (process.env.NODE_ENV !== 'production') {
7819
+ if (!hasWarned) {
7820
+ logWarn(`Hydration mismatch: incorrect number of rendered nodes. Server rendered more nodes than the client.`, owner);
7821
+ }
7822
+ }
7911
7823
  // nextSibling is mostly harmless, and since we don't have
7912
7824
  // a good reference to what element to act upon, we instead
7913
7825
  // rely on the vm's associated renderer for navigating to the
@@ -7919,14 +7831,6 @@ expectAddlSiblings) {
7919
7831
  removeNode(current, parentNode, renderer);
7920
7832
  } while (nextNode);
7921
7833
  }
7922
- if (mismatchedChildren) {
7923
- hasMismatch = true;
7924
- // We can't know exactly which node(s) caused the delta, but we can provide context (parent) and the mismatched sets
7925
- if (process.env.NODE_ENV !== 'production') {
7926
- const clientNodes = ArrayMap.call(children, (c) => c?.elm);
7927
- queueHydrationError('child node', serverNodes, clientNodes);
7928
- }
7929
- }
7930
7834
  }
7931
7835
  function handleMismatch(node, vnode, renderer) {
7932
7836
  hasMismatch = true;
@@ -7942,21 +7846,31 @@ function patchElementPropsAndAttrsAndRefs(vnode, renderer) {
7942
7846
  // The `refs` object is blown away in every re-render, so we always need to re-apply them
7943
7847
  applyRefs(vnode, vnode.owner);
7944
7848
  }
7849
+ function hasCorrectNodeType(vnode, node, nodeType, renderer) {
7850
+ const { getProperty } = renderer;
7851
+ if (getProperty(node, 'nodeType') !== nodeType) {
7852
+ if (process.env.NODE_ENV !== 'production') {
7853
+ logWarn('Hydration mismatch: incorrect node type received', vnode.owner);
7854
+ }
7855
+ return false;
7856
+ }
7857
+ return true;
7858
+ }
7945
7859
  function isMatchingElement(vnode, elm, renderer, shouldValidateAttr = () => true) {
7946
7860
  const { getProperty } = renderer;
7947
7861
  if (vnode.sel.toLowerCase() !== getProperty(elm, 'tagName').toLowerCase()) {
7948
7862
  if (process.env.NODE_ENV !== 'production') {
7949
- queueHydrationError('node', elm);
7863
+ logWarn(`Hydration mismatch: expecting element with tag "${vnode.sel.toLowerCase()}" but found "${getProperty(elm, 'tagName').toLowerCase()}".`, vnode.owner);
7950
7864
  }
7951
7865
  return false;
7952
7866
  }
7953
7867
  const { data } = vnode;
7954
- const hasCompatibleAttrs = validateAttrs(elm, data, renderer, shouldValidateAttr);
7868
+ const hasCompatibleAttrs = validateAttrs(vnode, elm, data, renderer, shouldValidateAttr);
7955
7869
  const hasCompatibleClass = shouldValidateAttr('class')
7956
7870
  ? validateClassAttr(vnode, elm, data, renderer)
7957
7871
  : true;
7958
7872
  const hasCompatibleStyle = shouldValidateAttr('style')
7959
- ? validateStyleAttr(elm, data, renderer)
7873
+ ? validateStyleAttr(vnode, elm, data, renderer)
7960
7874
  : true;
7961
7875
  return hasCompatibleAttrs && hasCompatibleClass && hasCompatibleStyle;
7962
7876
  }
@@ -7973,7 +7887,7 @@ function attributeValuesAreEqual(vnodeValue, value) {
7973
7887
  // In all other cases, the two values are not considered equal
7974
7888
  return false;
7975
7889
  }
7976
- function validateAttrs(elm, data, renderer, shouldValidateAttr) {
7890
+ function validateAttrs(vnode, elm, data, renderer, shouldValidateAttr) {
7977
7891
  const { attrs = {} } = data;
7978
7892
  let nodesAreCompatible = true;
7979
7893
  // Validate attributes, though we could always recovery from those by running the update mods.
@@ -7986,7 +7900,8 @@ function validateAttrs(elm, data, renderer, shouldValidateAttr) {
7986
7900
  const elmAttrValue = getAttribute(elm, attrName);
7987
7901
  if (!attributeValuesAreEqual(attrValue, elmAttrValue)) {
7988
7902
  if (process.env.NODE_ENV !== 'production') {
7989
- queueHydrationError('attribute', prettyPrintAttribute(attrName, elmAttrValue), prettyPrintAttribute(attrName, attrValue));
7903
+ const { getProperty } = renderer;
7904
+ logWarn(`Mismatch hydrating element <${getProperty(elm, 'tagName').toLowerCase()}>: attribute "${attrName}" has different values, expected "${attrValue}" but found ${isNull(elmAttrValue) ? 'null' : `"${elmAttrValue}"`}`, vnode.owner);
7990
7905
  }
7991
7906
  nodesAreCompatible = false;
7992
7907
  }
@@ -8014,6 +7929,7 @@ function validateClassAttr(vnode, elm, data, renderer) {
8014
7929
  // classMap is never available on VStaticPartData so it can default to undefined
8015
7930
  // casting to prevent TS error.
8016
7931
  const { className, classMap } = data;
7932
+ const { getProperty } = renderer;
8017
7933
  // ---------- Step 1: get the classes from the element and the vnode
8018
7934
  // Use a Set because we don't care to validate mismatches for 1) different ordering in SSR vs CSR, or 2)
8019
7935
  // duplicated class names. These don't have an effect on rendered styles.
@@ -8059,11 +7975,12 @@ function validateClassAttr(vnode, elm, data, renderer) {
8059
7975
  // ---------- Step 3: check for compatibility
8060
7976
  const classesAreCompatible = checkClassesCompatibility(vnodeClasses, elmClasses);
8061
7977
  if (process.env.NODE_ENV !== 'production' && !classesAreCompatible) {
8062
- queueHydrationError('attribute', prettyPrintClasses(elmClasses), prettyPrintClasses(vnodeClasses));
7978
+ const prettyPrint = (set) => JSON.stringify(ArrayJoin.call(ArraySort.call(ArrayFrom(set)), ' '));
7979
+ logWarn(`Mismatch hydrating element <${getProperty(elm, 'tagName').toLowerCase()}>: attribute "class" has different values, expected ${prettyPrint(vnodeClasses)} but found ${prettyPrint(elmClasses)}`, vnode.owner);
8063
7980
  }
8064
7981
  return classesAreCompatible;
8065
7982
  }
8066
- function validateStyleAttr(elm, data, renderer) {
7983
+ function validateStyleAttr(vnode, elm, data, renderer) {
8067
7984
  // Note styleDecls is always undefined for VStaticPartData, casting here to default it to undefined
8068
7985
  const { style, styleDecls } = data;
8069
7986
  const { getAttribute } = renderer;
@@ -8097,33 +8014,49 @@ function validateStyleAttr(elm, data, renderer) {
8097
8014
  }
8098
8015
  vnodeStyle = ArrayJoin.call(expectedStyle, ' ');
8099
8016
  }
8100
- if (process.env.NODE_ENV !== 'production' && !nodesAreCompatible) {
8101
- queueHydrationError('attribute', prettyPrintAttribute('style', elmStyle), prettyPrintAttribute('style', vnodeStyle));
8017
+ if (!nodesAreCompatible) {
8018
+ if (process.env.NODE_ENV !== 'production') {
8019
+ const { getProperty } = renderer;
8020
+ logWarn(`Mismatch hydrating element <${getProperty(elm, 'tagName').toLowerCase()}>: attribute "style" has different values, expected "${vnodeStyle}" but found "${elmStyle}".`, vnode.owner);
8021
+ }
8102
8022
  }
8103
8023
  return nodesAreCompatible;
8104
8024
  }
8105
- function areStaticElementsCompatible(clientElement, serverElement, vnode, renderer) {
8025
+ function areCompatibleStaticNodes(client, ssr, vnode, renderer) {
8106
8026
  const { getProperty, getAttribute } = renderer;
8107
- const { parts } = vnode;
8027
+ if (getProperty(client, 'nodeType') === 3 /* EnvNodeTypes.TEXT */) {
8028
+ if (!hasCorrectNodeType(vnode, ssr, 3 /* EnvNodeTypes.TEXT */, renderer)) {
8029
+ return false;
8030
+ }
8031
+ return getProperty(client, NODE_VALUE_PROP) === getProperty(ssr, NODE_VALUE_PROP);
8032
+ }
8033
+ if (getProperty(client, 'nodeType') === 8 /* EnvNodeTypes.COMMENT */) {
8034
+ if (!hasCorrectNodeType(vnode, ssr, 8 /* EnvNodeTypes.COMMENT */, renderer)) {
8035
+ return false;
8036
+ }
8037
+ return getProperty(client, NODE_VALUE_PROP) === getProperty(ssr, NODE_VALUE_PROP);
8038
+ }
8039
+ if (!hasCorrectNodeType(vnode, ssr, 1 /* EnvNodeTypes.ELEMENT */, renderer)) {
8040
+ return false;
8041
+ }
8042
+ const { owner, parts } = vnode;
8108
8043
  let isCompatibleElements = true;
8109
- if (getProperty(clientElement, 'tagName') !== getProperty(serverElement, 'tagName')) {
8044
+ if (getProperty(client, 'tagName') !== getProperty(ssr, 'tagName')) {
8110
8045
  if (process.env.NODE_ENV !== 'production') {
8111
- queueHydrationError('node', serverElement);
8046
+ logWarn(`Hydration mismatch: expecting element with tag "${getProperty(client, 'tagName').toLowerCase()}" but found "${getProperty(ssr, 'tagName').toLowerCase()}".`, owner);
8112
8047
  }
8113
8048
  return false;
8114
8049
  }
8115
- const clientAttrsNames = getProperty(clientElement, 'getAttributeNames').call(clientElement);
8050
+ const clientAttrsNames = getProperty(client, 'getAttributeNames').call(client);
8116
8051
  clientAttrsNames.forEach((attrName) => {
8117
- const clientAttributeValue = getAttribute(clientElement, attrName);
8118
- const serverAttributeValue = getAttribute(serverElement, attrName);
8119
- if (clientAttributeValue !== serverAttributeValue) {
8052
+ if (getAttribute(client, attrName) !== getAttribute(ssr, attrName)) {
8120
8053
  // Check if the root element attributes have expressions, if it does then we need to delegate hydration
8121
8054
  // validation to haveCompatibleStaticParts.
8122
8055
  // Note if there are no parts then it is a fully static fragment.
8123
8056
  // partId === 0 will always refer to the root element, this is guaranteed by the compiler.
8124
8057
  if (parts?.[0].partId !== 0) {
8125
8058
  if (process.env.NODE_ENV !== 'production') {
8126
- queueHydrationError('attribute', prettyPrintAttribute(attrName, serverAttributeValue), prettyPrintAttribute(attrName, clientAttributeValue));
8059
+ logWarn(`Mismatch hydrating element <${getProperty(client, 'tagName').toLowerCase()}>: attribute "${attrName}" has different values, expected "${getAttribute(client, attrName)}" but found "${getAttribute(ssr, attrName)}"`, owner);
8127
8060
  }
8128
8061
  isCompatibleElements = false;
8129
8062
  }
@@ -8132,7 +8065,7 @@ function areStaticElementsCompatible(clientElement, serverElement, vnode, render
8132
8065
  return isCompatibleElements;
8133
8066
  }
8134
8067
  function haveCompatibleStaticParts(vnode, renderer) {
8135
- const { parts } = vnode;
8068
+ const { parts, owner } = vnode;
8136
8069
  if (isUndefined$1(parts)) {
8137
8070
  return true;
8138
8071
  }
@@ -8143,11 +8076,11 @@ function haveCompatibleStaticParts(vnode, renderer) {
8143
8076
  for (const part of parts) {
8144
8077
  const { elm } = part;
8145
8078
  if (isVStaticPartElement(part)) {
8146
- if (!isTypeElement(elm)) {
8079
+ if (!hasCorrectNodeType(vnode, elm, 1 /* EnvNodeTypes.ELEMENT */, renderer)) {
8147
8080
  return false;
8148
8081
  }
8149
8082
  const { data } = part;
8150
- const hasMatchingAttrs = validateAttrs(elm, data, renderer, () => true);
8083
+ const hasMatchingAttrs = validateAttrs(vnode, elm, data, renderer, () => true);
8151
8084
  // Explicitly skip hydration validation when static parts don't contain `style` or `className`.
8152
8085
  // This means the style/class attributes are either static or don't exist on the element and
8153
8086
  // cannot be affected by hydration.
@@ -8157,7 +8090,7 @@ function haveCompatibleStaticParts(vnode, renderer) {
8157
8090
  ? validateClassAttr(vnode, elm, data, renderer)
8158
8091
  : true;
8159
8092
  const hasMatchingStyleAttr = shouldValidateAttr(data, 'style')
8160
- ? validateStyleAttr(elm, data, renderer)
8093
+ ? validateStyleAttr(vnode, elm, data, renderer)
8161
8094
  : true;
8162
8095
  if (isFalse(hasMatchingAttrs && hasMatchingClass && hasMatchingStyleAttr)) {
8163
8096
  return false;
@@ -8165,10 +8098,10 @@ function haveCompatibleStaticParts(vnode, renderer) {
8165
8098
  }
8166
8099
  else {
8167
8100
  // VStaticPartText
8168
- if (!isTypeText(elm)) {
8101
+ if (!hasCorrectNodeType(vnode, elm, 3 /* EnvNodeTypes.TEXT */, renderer)) {
8169
8102
  return false;
8170
8103
  }
8171
- updateTextContent(elm, part, renderer);
8104
+ updateTextContent(elm, part, owner, renderer);
8172
8105
  }
8173
8106
  }
8174
8107
  return true;
@@ -8434,5 +8367,5 @@ function readonly(obj) {
8434
8367
  }
8435
8368
 
8436
8369
  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 };
8437
- /** version: 8.12.6 */
8370
+ /** version: 8.12.2 */
8438
8371
  //# sourceMappingURL=index.js.map