@lwc/engine-core 8.12.7-alpha.0 → 8.12.7

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