@lwc/engine-core 2.5.6 → 2.5.10-alpha1

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,5 +1,5 @@
1
1
  /* proxy-compat-disable */
2
- import { seal, create, isFunction as isFunction$1, ArrayPush as ArrayPush$1, isUndefined as isUndefined$1, ArrayIndexOf, ArraySplice, StringToLowerCase, ArrayJoin, isNull, assign, assert, keys, StringCharCodeAt, isString, StringSlice, freeze, defineProperties, forEach, getOwnPropertyNames as getOwnPropertyNames$1, getPrototypeOf as getPrototypeOf$1, setPrototypeOf, getPropertyDescriptor, isObject, AriaPropNameToAttrNameMap, defineProperty, KEY__SYNTHETIC_MODE, toString as toString$1, isFalse, isTrue, getOwnPropertyDescriptor as getOwnPropertyDescriptor$1, htmlPropertyToAttribute, ArraySlice, hasOwnProperty as hasOwnProperty$1, noop, isArray as isArray$1, isNumber, StringReplace, KEY__SHADOW_RESOLVER, KEY__SCOPED_CSS, ArrayUnshift, isFrozen } from '@lwc/shared';
2
+ import { seal, create, isFunction as isFunction$1, ArrayPush as ArrayPush$1, isUndefined as isUndefined$1, ArrayIndexOf, ArraySplice, StringToLowerCase, ArrayJoin, isNull, assign, assert, keys, StringCharCodeAt, isString, StringSlice, freeze, defineProperties, forEach, getOwnPropertyNames as getOwnPropertyNames$1, getPrototypeOf as getPrototypeOf$1, setPrototypeOf, getPropertyDescriptor, isObject, AriaPropNameToAttrNameMap, defineProperty, KEY__SYNTHETIC_MODE, toString as toString$1, isFalse, isTrue, getOwnPropertyDescriptor as getOwnPropertyDescriptor$1, htmlPropertyToAttribute, ArraySlice, hasOwnProperty as hasOwnProperty$1, ArrayFilter, noop, isArray as isArray$1, isNumber, StringReplace, KEY__SHADOW_RESOLVER, KEY__SCOPED_CSS, ArrayUnshift, isFrozen } from '@lwc/shared';
3
3
  import { runtimeFlags } from '@lwc/features';
4
4
  export { setFeatureFlag, setFeatureFlagForTest } from '@lwc/features';
5
5
 
@@ -48,6 +48,26 @@ function guid() {
48
48
  }
49
49
 
50
50
  return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
51
+ } // Borrowed from Vue template compiler.
52
+ // https://github.com/vuejs/vue/blob/531371b818b0e31a989a06df43789728f23dc4e8/src/platforms/web/util/style.js#L5-L16
53
+
54
+ const DECLARATION_DELIMITER = /;(?![^(]*\))/g;
55
+ const PROPERTY_DELIMITER = /:(.+)/;
56
+ function parseStyleText(cssText) {
57
+ const styleMap = {};
58
+ const declarations = cssText.split(DECLARATION_DELIMITER);
59
+
60
+ for (const declaration of declarations) {
61
+ if (declaration) {
62
+ const [prop, value] = declaration.split(PROPERTY_DELIMITER);
63
+
64
+ if (prop !== undefined && value !== undefined) {
65
+ styleMap[prop.trim()] = value.trim();
66
+ }
67
+ }
68
+ }
69
+
70
+ return styleMap;
51
71
  }
52
72
 
53
73
  /*
@@ -219,8 +239,9 @@ function getErrorComponentStack(vm) {
219
239
  * SPDX-License-Identifier: MIT
220
240
  * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
221
241
  */
222
- function logError(message, vm) {
223
- let msg = `[LWC error]: ${message}`;
242
+
243
+ function log(method, message, vm) {
244
+ let msg = `[LWC ${method}]: ${message}`;
224
245
 
225
246
  if (!isUndefined$1(vm)) {
226
247
  msg = `${msg}\n${getComponentStack(vm)}`;
@@ -228,7 +249,7 @@ function logError(message, vm) {
228
249
 
229
250
  if (process.env.NODE_ENV === 'test') {
230
251
  /* eslint-disable-next-line no-console */
231
- console.error(msg);
252
+ console[method](msg);
232
253
  return;
233
254
  }
234
255
 
@@ -236,10 +257,17 @@ function logError(message, vm) {
236
257
  throw new Error(msg);
237
258
  } catch (e) {
238
259
  /* eslint-disable-next-line no-console */
239
- console.error(e);
260
+ console[method](e);
240
261
  }
241
262
  }
242
263
 
264
+ function logError(message, vm) {
265
+ log('error', message, vm);
266
+ }
267
+ function logWarn(message, vm) {
268
+ log('warn', message, vm);
269
+ }
270
+
243
271
  /*
244
272
  * Copyright (c) 2018, salesforce.com, inc.
245
273
  * All rights reserved.
@@ -2593,8 +2621,10 @@ for (const [elementProp, rendererMethod] of childGetters) {
2593
2621
  }
2594
2622
 
2595
2623
  return renderer[rendererMethod](elm);
2596
- }
2624
+ },
2597
2625
 
2626
+ configurable: true,
2627
+ enumerable: true
2598
2628
  };
2599
2629
  }
2600
2630
 
@@ -2614,8 +2644,11 @@ for (const queryMethod of queryMethods) {
2614
2644
  }
2615
2645
 
2616
2646
  return renderer[queryMethod](elm, arg);
2617
- }
2647
+ },
2618
2648
 
2649
+ configurable: true,
2650
+ enumerable: true,
2651
+ writable: true
2619
2652
  };
2620
2653
  }
2621
2654
 
@@ -3747,7 +3780,7 @@ function createComponentDef(Ctor) {
3747
3780
  if (!isUndefined$1(ctorShadowSupportMode)) {
3748
3781
  assert.invariant(ctorShadowSupportMode === "any"
3749
3782
  /* Any */
3750
- || ctorShadowSupportMode === "default"
3783
+ || ctorShadowSupportMode === "reset"
3751
3784
  /* Default */
3752
3785
  , `Invalid value for static property shadowSupportMode: '${ctorShadowSupportMode}'`);
3753
3786
  }
@@ -3907,7 +3940,7 @@ const lightingElementDef = {
3907
3940
  renderMode: 1
3908
3941
  /* Shadow */
3909
3942
  ,
3910
- shadowSupportMode: "default"
3943
+ shadowSupportMode: "reset"
3911
3944
  /* Default */
3912
3945
  ,
3913
3946
  wire: EmptyObject,
@@ -4052,6 +4085,16 @@ function createElmHook(vnode) {
4052
4085
  modComputedClassName.create(vnode);
4053
4086
  modComputedStyle.create(vnode);
4054
4087
  }
4088
+ function hydrateElmHook(vnode) {
4089
+ modEvents.create(vnode); // Attrs are already on the element.
4090
+ // modAttrs.create(vnode);
4091
+
4092
+ modProps.create(vnode); // Already set.
4093
+ // modStaticClassName.create(vnode);
4094
+ // modStaticStyle.create(vnode);
4095
+ // modComputedClassName.create(vnode);
4096
+ // modComputedStyle.create(vnode);
4097
+ }
4055
4098
  function fallbackElmHook(elm, vnode) {
4056
4099
  const {
4057
4100
  owner
@@ -4216,6 +4259,179 @@ function createChildrenHook(vnode) {
4216
4259
  }
4217
4260
  }
4218
4261
  }
4262
+
4263
+ function isElementNode(node) {
4264
+ // eslint-disable-next-line lwc-internal/no-global-node
4265
+ return node.nodeType === Node.ELEMENT_NODE;
4266
+ }
4267
+
4268
+ function vnodesAndElementHaveCompatibleAttrs(vnode, elm) {
4269
+ const {
4270
+ data: {
4271
+ attrs = {}
4272
+ },
4273
+ owner: {
4274
+ renderer
4275
+ }
4276
+ } = vnode;
4277
+ let nodesAreCompatible = true; // Validate attributes, though we could always recovery from those by running the update mods.
4278
+ // Note: intentionally ONLY matching vnodes.attrs to elm.attrs, in case SSR is adding extra attributes.
4279
+
4280
+ for (const [attrName, attrValue] of Object.entries(attrs)) {
4281
+ const elmAttrValue = renderer.getAttribute(elm, attrName);
4282
+
4283
+ if (String(attrValue) !== elmAttrValue) {
4284
+ logError(`Mismatch hydrating element <${elm.tagName.toLowerCase()}>: attribute "${attrName}" has different values, expected "${attrValue}" but found "${elmAttrValue}"`, vnode.owner);
4285
+ nodesAreCompatible = false;
4286
+ }
4287
+ }
4288
+
4289
+ return nodesAreCompatible;
4290
+ }
4291
+
4292
+ function vnodesAndElementHaveCompatibleClass(vnode, elm) {
4293
+ const {
4294
+ data: {
4295
+ className,
4296
+ classMap
4297
+ },
4298
+ owner: {
4299
+ renderer
4300
+ }
4301
+ } = vnode;
4302
+ let nodesAreCompatible = true;
4303
+ let vnodeClassName;
4304
+
4305
+ if (!isUndefined$1(className) && String(className) !== elm.className) {
4306
+ // className is used when class is bound to an expr.
4307
+ nodesAreCompatible = false;
4308
+ vnodeClassName = className;
4309
+ } else if (!isUndefined$1(classMap)) {
4310
+ // classMap is used when class is set to static value.
4311
+ const classList = renderer.getClassList(elm);
4312
+ let computedClassName = ''; // all classes from the vnode should be in the element.classList
4313
+
4314
+ for (const name in classMap) {
4315
+ computedClassName += ' ' + name;
4316
+
4317
+ if (!classList.contains(name)) {
4318
+ nodesAreCompatible = false;
4319
+ }
4320
+ }
4321
+
4322
+ vnodeClassName = computedClassName.trim();
4323
+
4324
+ if (classList.length > keys(classMap).length) {
4325
+ nodesAreCompatible = false;
4326
+ }
4327
+ }
4328
+
4329
+ if (!nodesAreCompatible) {
4330
+ logError(`Mismatch hydrating element <${elm.tagName.toLowerCase()}>: attribute "class" has different values, expected "${vnodeClassName}" but found "${elm.className}"`, vnode.owner);
4331
+ }
4332
+
4333
+ return nodesAreCompatible;
4334
+ }
4335
+
4336
+ function vnodesAndElementHaveCompatibleStyle(vnode, elm) {
4337
+ const {
4338
+ data: {
4339
+ style,
4340
+ styleDecls
4341
+ },
4342
+ owner: {
4343
+ renderer
4344
+ }
4345
+ } = vnode;
4346
+ const elmStyle = renderer.getAttribute(elm, 'style') || '';
4347
+ let vnodeStyle;
4348
+ let nodesAreCompatible = true;
4349
+
4350
+ if (!isUndefined$1(style) && style !== elmStyle) {
4351
+ nodesAreCompatible = false;
4352
+ vnodeStyle = style;
4353
+ } else if (!isUndefined$1(styleDecls)) {
4354
+ const parsedVnodeStyle = parseStyleText(elmStyle);
4355
+ const expectedStyle = []; // styleMap is used when style is set to static value.
4356
+
4357
+ for (let i = 0, n = styleDecls.length; i < n; i++) {
4358
+ const [prop, value, important] = styleDecls[i];
4359
+ expectedStyle.push(`${prop}: ${value + (important ? ' important!' : '')}`);
4360
+ const parsedPropValue = parsedVnodeStyle[prop];
4361
+
4362
+ if (isUndefined$1(parsedPropValue)) {
4363
+ nodesAreCompatible = false;
4364
+ } else if (!parsedPropValue.startsWith(value)) {
4365
+ nodesAreCompatible = false;
4366
+ } else if (important && !parsedPropValue.endsWith('!important')) {
4367
+ nodesAreCompatible = false;
4368
+ }
4369
+ }
4370
+
4371
+ if (keys(parsedVnodeStyle).length > styleDecls.length) {
4372
+ nodesAreCompatible = false;
4373
+ }
4374
+
4375
+ vnodeStyle = ArrayJoin.call(expectedStyle, ';');
4376
+ }
4377
+
4378
+ if (!nodesAreCompatible) {
4379
+ // style is used when class is bound to an expr.
4380
+ logError(`Mismatch hydrating element <${elm.tagName.toLowerCase()}>: attribute "style" has different values, expected "${vnodeStyle}" but found "${elmStyle}".`, vnode.owner);
4381
+ }
4382
+
4383
+ return nodesAreCompatible;
4384
+ }
4385
+
4386
+ function throwHydrationError() {
4387
+ assert.fail('Server rendered elements do not match client side generated elements');
4388
+ }
4389
+
4390
+ function hydrateChildrenHook(elmChildren, children, vm) {
4391
+ var _a, _b;
4392
+
4393
+ if (process.env.NODE_ENV !== 'production') {
4394
+ const filteredVNodes = ArrayFilter.call(children, vnode => !!vnode);
4395
+
4396
+ if (elmChildren.length !== filteredVNodes.length) {
4397
+ logError(`Hydration mismatch: incorrect number of rendered nodes, expected ${filteredVNodes.length} but found ${elmChildren.length}.`, vm);
4398
+ throwHydrationError();
4399
+ }
4400
+ }
4401
+
4402
+ let elmCurrentChildIdx = 0;
4403
+
4404
+ for (let j = 0, n = children.length; j < n; j++) {
4405
+ const ch = children[j];
4406
+
4407
+ if (ch != null) {
4408
+ const childNode = elmChildren[elmCurrentChildIdx];
4409
+
4410
+ if (process.env.NODE_ENV !== 'production') {
4411
+ // VComments and VTexts validation is handled in their hooks
4412
+ if (isElementNode(childNode)) {
4413
+ if (((_a = ch.sel) === null || _a === void 0 ? void 0 : _a.toLowerCase()) !== childNode.tagName.toLowerCase()) {
4414
+ logError(`Hydration mismatch: expecting element with tag "${(_b = ch.sel) === null || _b === void 0 ? void 0 : _b.toLowerCase()}" but found "${childNode.tagName.toLowerCase()}".`, vm);
4415
+ throwHydrationError();
4416
+ } // Note: props are not yet set
4417
+
4418
+
4419
+ const hasIncompatibleAttrs = vnodesAndElementHaveCompatibleAttrs(ch, childNode);
4420
+ const hasIncompatibleClass = vnodesAndElementHaveCompatibleClass(ch, childNode);
4421
+ const hasIncompatibleStyle = vnodesAndElementHaveCompatibleStyle(ch, childNode);
4422
+ const isVNodeAndElementCompatible = hasIncompatibleAttrs && hasIncompatibleClass && hasIncompatibleStyle;
4423
+
4424
+ if (!isVNodeAndElementCompatible) {
4425
+ throwHydrationError();
4426
+ }
4427
+ }
4428
+ }
4429
+
4430
+ ch.hook.hydrate(ch, childNode);
4431
+ elmCurrentChildIdx++;
4432
+ }
4433
+ }
4434
+ }
4219
4435
  function updateCustomElmHook(oldVnode, vnode) {
4220
4436
  // Attrs need to be applied to element before props
4221
4437
  // IE11 will wipe out value on radio inputs if value
@@ -4289,36 +4505,6 @@ function getUpgradableConstructor(tagName, renderer) {
4289
4505
  return CE;
4290
4506
  }
4291
4507
 
4292
- /*
4293
- * Copyright (c) 2018, salesforce.com, inc.
4294
- * All rights reserved.
4295
- * SPDX-License-Identifier: MIT
4296
- * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
4297
- */
4298
-
4299
- /**
4300
- * EXPERIMENTAL: This function acts like a hook for Lightning Locker Service and other similar
4301
- * libraries to sanitize HTML content. This hook process the content passed via the template to
4302
- * lwc:inner-html directive.
4303
- * It is meant to be overridden with setSanitizeHtmlContentHook
4304
- */
4305
- let sanitizeHtmlContentHook = () => {
4306
- // locker-service patches this function during runtime to sanitize HTML content.
4307
- throw new Error('sanitizeHtmlContent hook must be implemented.');
4308
- };
4309
- /**
4310
- * Sets the sanitizeHtmlContentHook.
4311
- *
4312
- * @param newHookImpl
4313
- * @returns oldHookImplementation.
4314
- */
4315
-
4316
- function setSanitizeHtmlContentHook(newHookImpl) {
4317
- const currentHook = sanitizeHtmlContentHook;
4318
- sanitizeHtmlContentHook = newHookImpl;
4319
- return currentHook;
4320
- }
4321
-
4322
4508
  /*
4323
4509
  * Copyright (c) 2018, salesforce.com, inc.
4324
4510
  * All rights reserved.
@@ -4342,7 +4528,26 @@ const TextHook = {
4342
4528
  update: updateNodeHook,
4343
4529
  insert: insertNodeHook,
4344
4530
  move: insertNodeHook,
4345
- remove: removeNodeHook
4531
+ remove: removeNodeHook,
4532
+ hydrate: (vNode, node) => {
4533
+ var _a;
4534
+
4535
+ if (process.env.NODE_ENV !== 'production') {
4536
+ // eslint-disable-next-line lwc-internal/no-global-node
4537
+ if (node.nodeType !== Node.TEXT_NODE) {
4538
+ logError('Hydration mismatch: incorrect node type received', vNode.owner);
4539
+ assert.fail('Hydration mismatch: incorrect node type received.');
4540
+ }
4541
+
4542
+ if (node.nodeValue !== vNode.text) {
4543
+ logWarn('Hydration mismatch: text values do not match, will recover from the difference', vNode.owner);
4544
+ }
4545
+ } // always set the text value to the one from the vnode.
4546
+
4547
+
4548
+ node.nodeValue = (_a = vNode.text) !== null && _a !== void 0 ? _a : null;
4549
+ vNode.elm = node;
4550
+ }
4346
4551
  };
4347
4552
  const CommentHook = {
4348
4553
  create: vnode => {
@@ -4360,7 +4565,26 @@ const CommentHook = {
4360
4565
  update: updateNodeHook,
4361
4566
  insert: insertNodeHook,
4362
4567
  move: insertNodeHook,
4363
- remove: removeNodeHook
4568
+ remove: removeNodeHook,
4569
+ hydrate: (vNode, node) => {
4570
+ var _a;
4571
+
4572
+ if (process.env.NODE_ENV !== 'production') {
4573
+ // eslint-disable-next-line lwc-internal/no-global-node
4574
+ if (node.nodeType !== Node.COMMENT_NODE) {
4575
+ logError('Hydration mismatch: incorrect node type received', vNode.owner);
4576
+ assert.fail('Hydration mismatch: incorrect node type received.');
4577
+ }
4578
+
4579
+ if (node.nodeValue !== vNode.text) {
4580
+ logWarn('Hydration mismatch: comment values do not match, will recover from the difference', vNode.owner);
4581
+ }
4582
+ } // always set the text value to the one from the vnode.
4583
+
4584
+
4585
+ node.nodeValue = (_a = vNode.text) !== null && _a !== void 0 ? _a : null;
4586
+ vNode.elm = node;
4587
+ }
4364
4588
  }; // insert is called after update, which is used somewhere else (via a module)
4365
4589
  // to mark the vm as inserted, that means we cannot use update as the main channel
4366
4590
  // to rehydrate when dirty, because sometimes the element is not inserted just yet,
@@ -4400,6 +4624,38 @@ const ElementHook = {
4400
4624
  remove: (vnode, parentNode) => {
4401
4625
  removeNodeHook(vnode, parentNode);
4402
4626
  removeElmHook(vnode);
4627
+ },
4628
+ hydrate: (vnode, node) => {
4629
+ const elm = node;
4630
+ vnode.elm = elm;
4631
+ const {
4632
+ context
4633
+ } = vnode.data;
4634
+ const isDomManual = Boolean(!isUndefined$1(context) && !isUndefined$1(context.lwc) && context.lwc.dom === "manual"
4635
+ /* manual */
4636
+ );
4637
+
4638
+ if (isDomManual) {
4639
+ // it may be that this element has lwc:inner-html, we need to diff and in case are the same,
4640
+ // remove the innerHTML from props so it reuses the existing dom elements.
4641
+ const {
4642
+ props
4643
+ } = vnode.data;
4644
+
4645
+ if (!isUndefined$1(props) && !isUndefined$1(props.innerHTML)) {
4646
+ if (elm.innerHTML === props.innerHTML) {
4647
+ delete props.innerHTML;
4648
+ } else {
4649
+ logWarn(`Mismatch hydrating element <${elm.tagName.toLowerCase()}>: innerHTML values do not match for element, will recover from the difference`, vnode.owner);
4650
+ }
4651
+ }
4652
+ }
4653
+
4654
+ hydrateElmHook(vnode);
4655
+
4656
+ if (!isDomManual) {
4657
+ hydrateChildrenHook(vnode.elm.childNodes, vnode.children, vnode.owner);
4658
+ }
4403
4659
  }
4404
4660
  };
4405
4661
  const CustomElementHook = {
@@ -4491,6 +4747,44 @@ const CustomElementHook = {
4491
4747
  // will take care of disconnecting any child VM attached to its shadow as well.
4492
4748
  removeVM(vm);
4493
4749
  }
4750
+ },
4751
+ hydrate: (vnode, elm) => {
4752
+ // the element is created, but the vm is not
4753
+ const {
4754
+ sel,
4755
+ mode,
4756
+ ctor,
4757
+ owner
4758
+ } = vnode;
4759
+ const def = getComponentInternalDef(ctor);
4760
+ createVM(elm, def, {
4761
+ mode,
4762
+ owner,
4763
+ tagName: sel,
4764
+ renderer: owner.renderer
4765
+ });
4766
+ vnode.elm = elm;
4767
+ const vm = getAssociatedVM(elm);
4768
+ allocateChildrenHook(vnode, vm);
4769
+ hydrateElmHook(vnode); // Insert hook section:
4770
+
4771
+ if (process.env.NODE_ENV !== 'production') {
4772
+ assert.isTrue(vm.state === 0
4773
+ /* created */
4774
+ , `${vm} cannot be recycled.`);
4775
+ }
4776
+
4777
+ runConnectedCallback(vm);
4778
+
4779
+ if (vm.renderMode !== 0
4780
+ /* Light */
4781
+ ) {
4782
+ // VM is not rendering in Light DOM, we can proceed and hydrate the slotted content.
4783
+ // Note: for Light DOM, this is handled while hydrating the VM
4784
+ hydrateChildrenHook(vnode.elm.childNodes, vnode.children, vm);
4785
+ }
4786
+
4787
+ hydrateVM(vm);
4494
4788
  }
4495
4789
  };
4496
4790
 
@@ -4803,7 +5097,7 @@ function co(text) {
4803
5097
 
4804
5098
 
4805
5099
  function d(value) {
4806
- return value == null ? '' : value;
5100
+ return value == null ? '' : String(value);
4807
5101
  } // [b]ind function
4808
5102
 
4809
5103
 
@@ -4965,9 +5259,28 @@ function sc(vnodes) {
4965
5259
 
4966
5260
  markAsDynamicChildren(vnodes);
4967
5261
  return vnodes;
4968
- } // [s]anitize [h]tml [c]ontent
5262
+ }
5263
+ /**
5264
+ * EXPERIMENTAL: This function acts like a hook for Lightning Locker Service and other similar
5265
+ * libraries to sanitize HTML content. This hook process the content passed via the template to
5266
+ * lwc:inner-html directive.
5267
+ * It is meant to be overridden with setSanitizeHtmlContentHook, it throws an error by default.
5268
+ */
4969
5269
 
4970
5270
 
5271
+ let sanitizeHtmlContentHook = () => {
5272
+ // locker-service patches this function during runtime to sanitize HTML content.
5273
+ throw new Error('sanitizeHtmlContent hook must be implemented.');
5274
+ };
5275
+ /**
5276
+ * Sets the sanitizeHtmlContentHook.
5277
+ */
5278
+
5279
+
5280
+ function setSanitizeHtmlContentHook(newHookImpl) {
5281
+ sanitizeHtmlContentHook = newHookImpl;
5282
+ } // [s]anitize [h]tml [c]ontent
5283
+
4971
5284
  function shc(content) {
4972
5285
  return sanitizeHtmlContentHook(content);
4973
5286
  }
@@ -5159,7 +5472,10 @@ function createStylesheet(vm, stylesheets) {
5159
5472
  for (let i = 0; i < stylesheets.length; i++) {
5160
5473
  renderer.insertGlobalStylesheet(stylesheets[i]);
5161
5474
  }
5162
- } else if (renderer.ssr) {
5475
+ } else if (renderer.ssr || renderer.isHydrating()) {
5476
+ // Note: We need to ensure that during hydration, the stylesheets method is the same as those in ssr.
5477
+ // This works in the client, because the stylesheets are created, and cached in the VM
5478
+ // the first time the VM renders.
5163
5479
  // native shadow or light DOM, SSR
5164
5480
  const combinedStylesheetContent = ArrayJoin.call(stylesheets, '\n');
5165
5481
  return createInlineStyleVNode(combinedStylesheetContent);
@@ -5756,12 +6072,20 @@ function connectRootElement(elm) {
5756
6072
  /* GlobalHydrate */
5757
6073
  , vm);
5758
6074
  }
6075
+ function hydrateRootElement(elm) {
6076
+ const vm = getAssociatedVM(elm);
6077
+ runConnectedCallback(vm);
6078
+ hydrateVM(vm);
6079
+ }
5759
6080
  function disconnectRootElement(elm) {
5760
6081
  const vm = getAssociatedVM(elm);
5761
6082
  resetComponentStateWhenRemoved(vm);
5762
6083
  }
5763
6084
  function appendVM(vm) {
5764
6085
  rehydrate(vm);
6086
+ }
6087
+ function hydrateVM(vm) {
6088
+ hydrate(vm);
5765
6089
  } // just in case the component comes back, with this we guarantee re-rendering it
5766
6090
  // while preventing any attempt to rehydration until after reinsertion.
5767
6091
 
@@ -5992,6 +6316,22 @@ function rehydrate(vm) {
5992
6316
  }
5993
6317
  }
5994
6318
 
6319
+ function hydrate(vm) {
6320
+ if (isTrue(vm.isDirty)) {
6321
+ // manually diffing/patching here.
6322
+ // This routine is:
6323
+ // patchShadowRoot(vm, children);
6324
+ // -> addVnodes.
6325
+ const children = renderComponent(vm);
6326
+ vm.children = children;
6327
+ const vmChildren = vm.renderMode === 0
6328
+ /* Light */
6329
+ ? vm.elm.childNodes : vm.elm.shadowRoot.childNodes;
6330
+ hydrateChildrenHook(vmChildren, children, vm);
6331
+ runRenderedCallback(vm);
6332
+ }
6333
+ }
6334
+
5995
6335
  function patchShadowRoot(vm, newCh) {
5996
6336
  const {
5997
6337
  children: oldCh
@@ -6802,27 +7142,11 @@ function readonly(obj) {
6802
7142
  * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
6803
7143
  */
6804
7144
  let hooksAreSet = false;
6805
-
6806
- function overrideHooks(hooks) {
6807
- const oldHooks = {};
6808
-
6809
- if (!isUndefined$1(hooks.sanitizeHtmlContent)) {
6810
- oldHooks.sanitizeHtmlContent = setSanitizeHtmlContentHook(hooks.sanitizeHtmlContent);
6811
- }
6812
-
6813
- return oldHooks;
6814
- }
6815
-
6816
7145
  function setHooks(hooks) {
6817
7146
  assert.isFalse(hooksAreSet, 'Hooks are already overridden, only one definition is allowed.');
6818
- overrideHooks(hooks);
6819
7147
  hooksAreSet = true;
6820
- }
6821
- function setHooksForTest(hooks) {
6822
- if (process.env.NODE_ENV !== 'production') {
6823
- return overrideHooks(hooks);
6824
- }
7148
+ setSanitizeHtmlContentHook(hooks.sanitizeHtmlContent);
6825
7149
  }
6826
7150
 
6827
- export { LightningElement, profilerControl as __unstable__ProfilerControl, api$1 as api, connectRootElement, createContextProvider, createVM, disconnectRootElement, getAssociatedVMIfPresent, getComponentDef, getComponentInternalDef, getUpgradableConstructor, isComponentConstructor, readonly, register, registerComponent, registerDecorators, registerTemplate, sanitizeAttribute, setHooks, setHooksForTest, swapComponent, swapStyle, swapTemplate, track, unwrap, wire };
6828
- /* version: 2.5.6 */
7151
+ export { LightningElement, profilerControl as __unstable__ProfilerControl, api$1 as api, connectRootElement, createContextProvider, createVM, disconnectRootElement, getAssociatedVMIfPresent, getComponentDef, getComponentInternalDef, getUpgradableConstructor, hydrateRootElement, isComponentConstructor, readonly, register, registerComponent, registerDecorators, registerTemplate, sanitizeAttribute, setHooks, swapComponent, swapStyle, swapTemplate, track, unwrap, wire };
7152
+ /* version: 2.5.10-alpha1 */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lwc/engine-core",
3
- "version": "2.5.6",
3
+ "version": "2.5.10-alpha1",
4
4
  "description": "Core LWC engine APIs.",
5
5
  "homepage": "https://lwc.dev/",
6
6
  "repository": {
@@ -24,14 +24,14 @@
24
24
  "types/"
25
25
  ],
26
26
  "dependencies": {
27
- "@lwc/features": "2.5.6",
28
- "@lwc/shared": "2.5.6"
27
+ "@lwc/features": "2.5.10-alpha1",
28
+ "@lwc/shared": "2.5.10-alpha1"
29
29
  },
30
30
  "devDependencies": {
31
- "observable-membrane": "1.0.1"
31
+ "observable-membrane": "1.1.5"
32
32
  },
33
33
  "publishConfig": {
34
34
  "access": "public"
35
35
  },
36
- "gitHead": "34c0e425387f7322c233ee4de15f23a1c0336f52"
36
+ "gitHead": "b96b2d24f545c14a5c8984ab01081290afd5dc39"
37
37
  }
@@ -74,6 +74,7 @@ export interface Hooks<N extends VNode> {
74
74
  move: (vNode: N, parentNode: Node, referenceNode: Node | null) => void;
75
75
  update: (oldVNode: N, vNode: N) => void;
76
76
  remove: (vNode: N, parentNode: Node) => void;
77
+ hydrate: (vNode: N, node: Node) => void;
77
78
  }
78
79
  export interface Module<N extends VNode> {
79
80
  create?: (vNode: N) => void;
@@ -12,7 +12,7 @@ declare function i(iterable: Iterable<any>, factory: (value: any, index: number,
12
12
  declare function f(items: any[]): any[];
13
13
  declare function t(text: string): VText;
14
14
  declare function co(text: string): VComment;
15
- declare function d(value: any): string | any;
15
+ declare function d(value: any): string;
16
16
  declare function b(fn: EventListener): EventListener;
17
17
  declare function k(compilerKey: number, obj: any): string | void;
18
18
  declare function gid(id: string | undefined | null): string | null | undefined;
@@ -21,6 +21,11 @@ declare function fid(url: string | undefined | null): string | null | undefined;
21
21
  * create a dynamic component via `<x-foo lwc:dynamic={Ctor}>`
22
22
  */
23
23
  declare function dc(sel: string, Ctor: LightningElementConstructor | null | undefined, data: VElementData, children?: VNodes): VCustomElement | null;
24
+ export declare type SanitizeHtmlContentHook = (content: unknown) => string;
25
+ /**
26
+ * Sets the sanitizeHtmlContentHook.
27
+ */
28
+ export declare function setSanitizeHtmlContentHook(newHookImpl: SanitizeHtmlContentHook): void;
24
29
  declare function shc(content: unknown): string;
25
30
  declare const api: Readonly<{
26
31
  s: typeof s;
@@ -4,6 +4,10 @@ export declare function updateNodeHook(oldVnode: VNode, vnode: VNode): void;
4
4
  export declare function insertNodeHook(vnode: VNode, parentNode: Node, referenceNode: Node | null): void;
5
5
  export declare function removeNodeHook(vnode: VNode, parentNode: Node): void;
6
6
  export declare function createElmHook(vnode: VElement): void;
7
+ export declare const enum LWCDOMMode {
8
+ manual = "manual"
9
+ }
10
+ export declare function hydrateElmHook(vnode: VElement): void;
7
11
  export declare function fallbackElmHook(elm: Element, vnode: VElement): void;
8
12
  export declare function updateElmHook(oldVnode: VElement, vnode: VElement): void;
9
13
  export declare function updateChildrenHook(oldVnode: VElement, vnode: VElement): void;
@@ -11,6 +15,7 @@ export declare function allocateChildrenHook(vnode: VCustomElement, vm: VM): voi
11
15
  export declare function createViewModelHook(elm: HTMLElement, vnode: VCustomElement): void;
12
16
  export declare function createCustomElmHook(vnode: VCustomElement): void;
13
17
  export declare function createChildrenHook(vnode: VElement): void;
18
+ export declare function hydrateChildrenHook(elmChildren: NodeListOf<ChildNode>, children: VNodes, vm?: VM): void;
14
19
  export declare function updateCustomElmHook(oldVnode: VCustomElement, vnode: VCustomElement): void;
15
20
  export declare function removeElmHook(vnode: VElement): void;
16
21
  export declare function markAsDynamicChildren(children: VNodes): void;