@stencil/core 5.0.0-beta.3 → 5.0.0-beta.31

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 (36) hide show
  1. package/dist/app-data/index.d.ts +1 -1
  2. package/dist/{client-BRu0GtRn.mjs → client-DIvBaMnB.mjs} +182 -70
  3. package/dist/compiler/browser.d.ts +114 -81
  4. package/dist/compiler/browser.js +743 -339
  5. package/dist/compiler/index.d.mts +110 -2
  6. package/dist/compiler/index.mjs +3 -3
  7. package/dist/compiler/utils/index.d.mts +1 -1
  8. package/dist/{compiler-BPgV6bA4.mjs → compiler-BI12oAIV.mjs} +4840 -2899
  9. package/dist/declarations/stencil-public-compiler.d.ts +152 -129
  10. package/dist/declarations/stencil-public-docs.d.ts +23 -0
  11. package/dist/declarations/stencil-public-runtime.d.ts +62 -58
  12. package/dist/{index-DmHmu3y0.d.mts → index-BGUOG9Wc.d.mts} +6 -2
  13. package/dist/{index-BopBfjPu.d.mts → index-BogZpjP2.d.mts} +150 -127
  14. package/dist/{index-BXAcVN2j.d.ts → index-CicD4Pgn.d.ts} +59 -55
  15. package/dist/index.d.mts +3 -0
  16. package/dist/index.mjs +1 -1
  17. package/dist/jsx-runtime.d.mts +6 -0
  18. package/dist/jsx-runtime.mjs +1 -1
  19. package/dist/{node-75gQKkFz.mjs → node-D-21Ykxi.mjs} +41 -47
  20. package/dist/runtime/client/lazy.js +321 -200
  21. package/dist/runtime/client/runtime.d.ts +73 -66
  22. package/dist/runtime/client/runtime.js +321 -200
  23. package/dist/runtime/index.d.ts +4 -5
  24. package/dist/runtime/index.js +319 -198
  25. package/dist/runtime/server/index.d.mts +11 -11
  26. package/dist/runtime/server/index.mjs +371 -239
  27. package/dist/runtime/server/runner.d.mts +4 -4
  28. package/dist/runtime/server/runner.mjs +82 -54
  29. package/dist/signals/index.d.ts +11 -2
  30. package/dist/signals/index.js +14 -35
  31. package/dist/sys/node/index.d.mts +1 -1
  32. package/dist/sys/node/index.mjs +1 -1
  33. package/dist/sys/node/worker.mjs +2 -2
  34. package/dist/testing/index.d.mts +136 -120
  35. package/dist/testing/index.mjs +328 -212
  36. package/package.json +8 -4
@@ -3,14 +3,15 @@ import { MockWindow, setupGlobal } from "@stencil/mock-doc";
3
3
  import "typescript";
4
4
  import fs from "node:fs";
5
5
  import "picomatch";
6
- import { effect, effect as effect$1, signal } from "@preact/signals-core";
6
+ import * as SignalsCore from "@preact/signals-core";
7
7
  import path, { basename, dirname } from "path";
8
+ import resolve from "resolve";
8
9
  import "postcss";
9
- import "postcss-safe-parser";
10
+ import "postcss-nesting";
10
11
  import "postcss-selector-parser";
12
+ import "postcss-safe-parser";
11
13
  import "magic-string";
12
14
  import "rolldown";
13
- import resolve from "resolve";
14
15
  import "rolldown/utils";
15
16
  import "terser";
16
17
  import "css-what";
@@ -32,7 +33,7 @@ import "@rollup/pluginutils";
32
33
  import { createHash } from "crypto";
33
34
  import { afterAll, vi } from "vitest";
34
35
  //#region src/version.ts
35
- const version = "5.0.0-beta.3";
36
+ const version = "5.0.0-beta.31";
36
37
  const MEMBER_FLAGS = {
37
38
  String: 1,
38
39
  Number: 2,
@@ -379,6 +380,10 @@ const trimFalsy = (data) => {
379
380
  */
380
381
  const isDef = (v) => v != null && v !== void 0;
381
382
  /**
383
+ * This is just a no-op, don't expect it to do anything.
384
+ */
385
+ const noop = () => {};
386
+ /**
382
387
  * Check whether a value is a 'complex type', defined here as an object or a
383
388
  * function.
384
389
  *
@@ -640,7 +645,7 @@ const Env = {};
640
645
  //#endregion
641
646
  //#region src/testing/platform/testing-constants.ts
642
647
  const styles = /* @__PURE__ */ new Map();
643
- const modeResolutionChain = [];
648
+ const modeResolver = [];
644
649
  /**
645
650
  * A mapping of custom element tags (e.g. `my-component`) to their constructor
646
651
  */
@@ -1467,6 +1472,7 @@ const patchSlotAppendChild = (HostElementPrototype) => {
1467
1472
  const { slotName, slotNode } = findSlotFromSlottedNode(newChild, this);
1468
1473
  if (slotNode) {
1469
1474
  addSlotRelocateNode(newChild, slotNode);
1475
+ patchSlottedNode(newChild);
1470
1476
  const slotChildNodes = getSlotChildSiblings(slotNode, slotName);
1471
1477
  const appendAfter = slotChildNodes[slotChildNodes.length - 1];
1472
1478
  const insertedNode = internalCall(internalCall(appendAfter, "parentNode"), "insertBefore")(newChild, appendAfter.nextSibling);
@@ -1489,8 +1495,10 @@ const patchSlotRemoveChild = (ElementPrototype) => {
1489
1495
  ElementPrototype.__removeChild = ElementPrototype.removeChild;
1490
1496
  ElementPrototype.removeChild = function(toRemove) {
1491
1497
  if (toRemove && typeof toRemove["s-sn"] !== "undefined") {
1492
- if (getHostSlotNodes(this.__childNodes || this.childNodes, this.tagName, toRemove["s-sn"]) && toRemove.isConnected) {
1493
- toRemove.remove();
1498
+ const slotNode = getHostSlotNodes(this.__childNodes || this.childNodes, this.tagName, toRemove["s-sn"]);
1499
+ if (slotNode && toRemove.isConnected) {
1500
+ removeSlottedNode(toRemove);
1501
+ if (slotNode[0]) dispatchSlotChangeEvent(slotNode[0]);
1494
1502
  updateFallbackSlotVisibility(this);
1495
1503
  return;
1496
1504
  }
@@ -1513,6 +1521,7 @@ const patchSlotPrepend = (HostElementPrototype) => {
1513
1521
  const slotNode = getHostSlotNodes(internalCall(this, "childNodes"), this.tagName, slotName)[0];
1514
1522
  if (slotNode) {
1515
1523
  addSlotRelocateNode(newChild, slotNode, true);
1524
+ patchSlottedNode(newChild);
1516
1525
  const appendAfter = getSlotChildSiblings(slotNode, slotName)[0];
1517
1526
  const toReturn = internalCall(internalCall(appendAfter, "parentNode"), "insertBefore")(newChild, internalCall(appendAfter, "nextSibling"));
1518
1527
  dispatchSlotChangeEvent(slotNode);
@@ -1588,6 +1597,7 @@ const patchInsertBefore = (HostElementPrototype) => {
1588
1597
  }
1589
1598
  if (slotName === currentChild["s-sn"]) {
1590
1599
  addSlotRelocateNode(newChild, slotNode);
1600
+ patchSlottedNode(newChild);
1591
1601
  internalCall(internalCall(currentChild, "parentNode"), "insertBefore")(newChild, currentChild);
1592
1602
  dispatchSlotChangeEvent(slotNode);
1593
1603
  }
@@ -1666,10 +1676,21 @@ const patchChildSlotNodes = (elm) => {
1666
1676
  } });
1667
1677
  };
1668
1678
  /**
1669
- * Patches sibling accessors of a 'slotted' node within a non-shadow component.
1670
- * Meaning whilst stepping through a non-shadow element's nodes, only the mock 'lightDOM' nodes are returned.
1671
- * Especially relevant when rendering components via SSR... Frameworks will often try to reconcile their
1672
- * VDOM with the real DOM by stepping through nodes with 'nextSibling' et al.
1679
+ * Patches a node slotted into a non-shadow component so it behaves as it would in a native slot:
1680
+ * - `parentNode` returns the host element
1681
+ * - `remove()` fires `slotchange` on the node's slot
1682
+ *
1683
+ * @param node the slotted node to be patched
1684
+ */
1685
+ const patchSlottedNode = (node) => {
1686
+ patchParentNode(node);
1687
+ patchSlottedRemove(node);
1688
+ };
1689
+ /**
1690
+ * Patches a slotted node from SSR markup: everything {@link patchSlottedNode} does, plus its
1691
+ * sibling accessors, so whilst stepping through a non-shadow element's nodes only the mock
1692
+ * 'lightDOM' nodes are returned. Frameworks hydrating SSR output often reconcile their VDOM with
1693
+ * the real DOM by stepping through nodes with 'nextSibling' et al.
1673
1694
  * - `nextSibling`
1674
1695
  * - `nextElementSibling`
1675
1696
  * - `previousSibling`
@@ -1677,11 +1698,11 @@ const patchChildSlotNodes = (elm) => {
1677
1698
  *
1678
1699
  * @param node the slotted node to be patched
1679
1700
  */
1680
- const patchSlottedNode = (node) => {
1701
+ const patchSsrSlottedNode = (node) => {
1681
1702
  if (!node || node.__nextSibling !== void 0 || !globalThis.Node) return;
1682
1703
  patchNextSibling(node);
1683
1704
  patchPreviousSibling(node);
1684
- patchParentNode(node);
1705
+ patchSlottedNode(node);
1685
1706
  if (node.nodeType === Node.ELEMENT_NODE) {
1686
1707
  patchNextElementSibling(node);
1687
1708
  patchPreviousElementSibling(node);
@@ -1748,6 +1769,39 @@ const patchPreviousElementSibling = (element) => {
1748
1769
  } });
1749
1770
  };
1750
1771
  /**
1772
+ * Detaches a slotted node from where it physically sits in the component's rendered DOM, through
1773
+ * the unpatched accessors. Not via `remove()`: mock-doc's `remove()` calls
1774
+ * `parentNode.removeChild()`, and a slotted node's patched `parentNode` is the host, whose patched
1775
+ * `removeChild()` would come straight back here.
1776
+ *
1777
+ * @param node the slotted node to detach
1778
+ */
1779
+ const removeSlottedNode = (node) => {
1780
+ const parent = internalCall(node, "parentNode");
1781
+ if (parent) internalCall(parent, "removeChild")(node);
1782
+ };
1783
+ /**
1784
+ * Patches `remove()` on a node slotted into a non-shadow component, so that removing it fires
1785
+ * `slotchange` on its slot (and updates fallback content), as removing a node from a native slot
1786
+ * does. Stencil's own node moves, while `isTmpDisconnected` is set, don't fire it.
1787
+ *
1788
+ * @param node the slotted node to patch
1789
+ */
1790
+ const patchSlottedRemove = (node) => {
1791
+ const child = node;
1792
+ if (!child || child.__remove || typeof child.remove !== "function") return;
1793
+ child.__remove = child.remove;
1794
+ child.remove = function() {
1795
+ const host = this["s-ol"]?.parentElement;
1796
+ const { slotNode } = findSlotFromSlottedNode(this);
1797
+ removeSlottedNode(this);
1798
+ if (slotNode && !(plt.$flags$ & PLATFORM_FLAGS.isTmpDisconnected)) {
1799
+ dispatchSlotChangeEvent(slotNode);
1800
+ updateFallbackSlotVisibility(host);
1801
+ }
1802
+ };
1803
+ };
1804
+ /**
1751
1805
  * Patches the `parentNode` accessor of a non-shadow slotted node
1752
1806
  *
1753
1807
  * @param node the slotted node to be patched
@@ -2110,7 +2164,19 @@ const hydrateScopedToShadow = () => {
2110
2164
  registerStyle(scopeId, convertScopedToShadow(styleElements[i].innerHTML), allowCS);
2111
2165
  }
2112
2166
  };
2167
+ //#endregion
2168
+ //#region src/runtime/signals-core.ts
2169
+ const getCore = () => globalThis[Symbol.for("stencil.preact-signals-core")] ??= SignalsCore;
2170
+ const effect = (fn, options) => getCore().effect(fn, options);
2171
+ function signal(value, options) {
2172
+ return getCore().signal(value, options);
2173
+ }
2113
2174
  const getRegistry = () => customElements;
2175
+ /**
2176
+ * @param elm a defined component host
2177
+ * @returns the registry the host's class was defined in, else the active registry
2178
+ */
2179
+ const getHostRegistry = (elm) => elm.constructor._registry ?? getRegistry();
2114
2180
  //#endregion
2115
2181
  //#region src/runtime/vdom/set-accessor.ts
2116
2182
  /**
@@ -2154,7 +2220,7 @@ const setAccessor = (elm, memberName, oldValue, newValue, isSvg, flags, initialR
2154
2220
  attrMap.get(memberName)?.();
2155
2221
  if (!signalAttrDisposers.has(elm)) signalAttrDisposers.set(elm, attrMap);
2156
2222
  let prevVal = oldValue;
2157
- attrMap.set(memberName, effect$1(() => {
2223
+ attrMap.set(memberName, effect(() => {
2158
2224
  const curVal = newValue.value;
2159
2225
  setAccessor(elm, memberName, prevVal, curVal, isSvg, flags);
2160
2226
  prevVal = curVal;
@@ -2234,10 +2300,10 @@ const setAccessor = (elm, memberName, oldValue, newValue, isSvg, flags, initialR
2234
2300
  const isComplex = isComplexType(newValue);
2235
2301
  if (!BUILD.lazyLoad) {
2236
2302
  const isStandardAttr = ln.startsWith("aria-") || ln.startsWith("data-");
2237
- if (!isProp && !isStandardAttr && elm.tagName?.includes("-") && elm.tagName !== "SLOT-FB" && typeof customElements !== "undefined" && !customElements.get(elm.tagName.toLowerCase())) {
2303
+ if (!isProp && !isStandardAttr && elm.tagName?.includes("-") && elm.tagName !== "SLOT-FB" && !customElements.get(elm.tagName.toLowerCase())) {
2238
2304
  if (!elm["s-pp"]) elm["s-pp"] = /* @__PURE__ */ new Map();
2239
2305
  elm["s-pp"].set(memberName, newValue);
2240
- return;
2306
+ if (isComplex || /[A-Z]/.test(memberName)) return;
2241
2307
  }
2242
2308
  }
2243
2309
  if ((isProp || isComplex && newValue !== null) && !isSvg) try {
@@ -2355,6 +2421,7 @@ function sortedAttrNames(attrNames) {
2355
2421
  let scopeId;
2356
2422
  let contentRef;
2357
2423
  let hostTagName;
2424
+ let hostRegistry;
2358
2425
  let useNativeShadowDom = false;
2359
2426
  let checkSlotFallbackVisibility = false;
2360
2427
  let checkSlotRelocate = false;
@@ -2364,6 +2431,7 @@ let isSvgMode = false;
2364
2431
  * These ensure that ref callbacks are called in the correct order:
2365
2432
  * first all removal callbacks (with null), then all attachment callbacks (with elements).
2366
2433
  */
2434
+ const initialSlotChanges = /* @__PURE__ */ new Set();
2367
2435
  const refCallbacksToRemove = [];
2368
2436
  const refCallbacksToAttach = [];
2369
2437
  /** Disposers for signal subscriptions on individual DOM nodes (text nodes, <s-show> wrappers). */
@@ -2371,16 +2439,33 @@ const signalNodeDisposers = /* @__PURE__ */ new WeakMap();
2371
2439
  const disposeSignalVNode = (vnode) => {
2372
2440
  const elm = vnode.$elm$;
2373
2441
  if (elm) {
2374
- const dispose = signalNodeDisposers.get(elm);
2375
- if (dispose) {
2376
- dispose();
2377
- signalNodeDisposers.delete(elm);
2378
- }
2442
+ disposeTextSignal(elm);
2379
2443
  disposeAllSignalAttrs(elm);
2380
2444
  }
2381
2445
  vnode.$children$?.forEach(disposeSignalVNode);
2382
2446
  };
2383
2447
  /**
2448
+ * Tear down a text node's signal subscription, if it has one.
2449
+ * @param textNode the text node to unsubscribe
2450
+ */
2451
+ const disposeTextSignal = (textNode) => {
2452
+ const dispose = signalNodeDisposers.get(textNode);
2453
+ if (dispose) {
2454
+ dispose();
2455
+ signalNodeDisposers.delete(textNode);
2456
+ }
2457
+ };
2458
+ /**
2459
+ * Subscribe a text node to a signal, keeping its `data` in sync on every change.
2460
+ * @param textNode the text node to keep in sync
2461
+ * @param textSig the signal to subscribe to
2462
+ */
2463
+ const wireTextSignal = (textNode, textSig) => {
2464
+ signalNodeDisposers.set(textNode, effect(() => {
2465
+ textNode.data = String(textSig.value);
2466
+ }));
2467
+ };
2468
+ /**
2384
2469
  * Create a DOM Node corresponding to one of the children of a given VNode.
2385
2470
  *
2386
2471
  * @param oldParentVNode the parent VNode from the previous render
@@ -2402,13 +2487,7 @@ const createElm = (oldParentVNode, newParentVNode, childIndex) => {
2402
2487
  if (BUILD.isDev && newVNode.$elm$) consoleDevError(`The JSX ${newVNode.$text$ !== null ? `"${newVNode.$text$}" text` : `"${String(newVNode.$tag$)}" element`} node should not be shared within the same renderer. The renderer caches element lookups in order to improve performance. However, a side effect from this is that the exact same JSX node should not be reused. For more information please see https://stenciljs.com/docs/templating-jsx#avoid-shared-jsx-nodes`);
2403
2488
  if (BUILD.vdomText && newVNode.$text$ != null) {
2404
2489
  elm = newVNode.$elm$ = win.document.createTextNode(newVNode.$text$);
2405
- if (BUILD.vdomSignals && newVNode.$signal$) {
2406
- const textSig = newVNode.$signal$;
2407
- const textNode = elm;
2408
- signalNodeDisposers.set(textNode, effect$1(() => {
2409
- textNode.data = String(textSig.value);
2410
- }));
2411
- }
2490
+ if (BUILD.vdomSignals && newVNode.$signal$) wireTextSignal(elm, newVNode.$signal$);
2412
2491
  } else if (BUILD.slotRelocation && newVNode.$flags$ & VNODE_FLAGS.isSlotReference) {
2413
2492
  elm = newVNode.$elm$ = BUILD.isDebug || BUILD.hydrateServerSide ? slotReferenceDebugNode(newVNode) : win.document.createTextNode("");
2414
2493
  if (typeof newVNode.$attrs$?.slot === "string") elm["s-sa"] = newVNode.$attrs$.slot;
@@ -2417,8 +2496,7 @@ const createElm = (oldParentVNode, newParentVNode, childIndex) => {
2417
2496
  if (BUILD.svg && !isSvgMode) isSvgMode = newVNode.$tag$ === "svg";
2418
2497
  if (!win.document) throw new Error("No DOM environment available for rendering.");
2419
2498
  const tag = !useNativeShadowDom && BUILD.slotRelocation && newVNode.$flags$ & VNODE_FLAGS.isSlotFallback ? "slot-fb" : newVNode.$tag$;
2420
- const _reg = getRegistry();
2421
- const registryOpts = _reg !== win.customElements && tag.includes("-") ? { customElementRegistry: _reg } : void 0;
2499
+ const registryOpts = hostRegistry !== win.customElements && tag.includes("-") ? { customElementRegistry: hostRegistry } : void 0;
2422
2500
  elm = newVNode.$elm$ = BUILD.svg && isSvgMode ? win.document.createElementNS(SVG_NS, tag) : win.document.createElement(tag, registryOpts);
2423
2501
  if (BUILD.svg && isSvgMode && newVNode.$tag$ === "foreignObject") isSvgMode = false;
2424
2502
  if (BUILD.vdomAttribute) updateElement(null, newVNode, isSvgMode);
@@ -2676,7 +2754,7 @@ const updateChildren = (parentElm, oldCh, newVNode, newCh, isInitialRender = fal
2676
2754
  }
2677
2755
  if (BUILD.vdomKey && idxInOld >= 0) {
2678
2756
  elmToMove = oldCh[idxInOld];
2679
- if (elmToMove.$tag$ !== newStartVnode.$tag$) node = createElm(oldCh && oldCh[newStartIdx], newVNode, idxInOld);
2757
+ if (elmToMove.$tag$ !== newStartVnode.$tag$) node = createElm(oldCh && oldCh[newStartIdx], newVNode, newStartIdx);
2680
2758
  else {
2681
2759
  patch(elmToMove, newStartVnode, isInitialRender);
2682
2760
  oldCh[idxInOld] = void 0;
@@ -2769,7 +2847,17 @@ const patch = (oldVNode, newVNode, isInitialRender = false) => {
2769
2847
  else if (BUILD.hydrateClientSide && isInitialRender && BUILD.updatable && oldChildren !== null && newChildren === null) newVNode.$children$ = oldChildren;
2770
2848
  if (BUILD.svg && isSvgMode && tag === "svg") isSvgMode = false;
2771
2849
  } else if (BUILD.vdomText && BUILD.slotRelocation && (defaultHolder = elm["s-cr"])) defaultHolder.parentNode.textContent = text;
2772
- else if (BUILD.vdomText && oldVNode.$text$ !== text) elm.data = text;
2850
+ else if (BUILD.vdomText) {
2851
+ if (BUILD.vdomSignals && newVNode.$signal$) {
2852
+ if (newVNode.$signal$ !== oldVNode.$signal$) {
2853
+ disposeTextSignal(elm);
2854
+ wireTextSignal(elm, newVNode.$signal$);
2855
+ }
2856
+ } else {
2857
+ if (BUILD.vdomSignals && oldVNode.$signal$) disposeTextSignal(elm);
2858
+ if (oldVNode.$text$ !== text) elm.data = text;
2859
+ }
2860
+ }
2773
2861
  };
2774
2862
  /**
2775
2863
  * Component-global information about nodes which are either currently being
@@ -2898,10 +2986,13 @@ const insertBefore = (parent, newNode, reference, isInitialLoad) => {
2898
2986
  if (BUILD.scoped && typeof newNode["s-sn"] === "string" && !!newNode["s-sr"] && !!newNode["s-cr"]) addRemoveSlotScopedClass(newNode["s-cr"], newNode, parent, newNode.parentElement);
2899
2987
  else if (typeof newNode["s-sn"] === "string") {
2900
2988
  const hostElm = newNode["s-hn"] && parent.closest?.(newNode["s-hn"]);
2901
- if ((BUILD.lightDomPatches || BUILD.slotChildNodes || BUILD.patchAll && !!(hostElm && getHostRef(hostElm)?.$cmpMeta$.$flags$ & CMP_FLAGS.patchAll)) && parent.getRootNode().nodeType !== NODE_TYPES.DOCUMENT_FRAGMENT_NODE) patchParentNode(newNode);
2989
+ if ((BUILD.lightDomPatches || BUILD.slotChildNodes || BUILD.patchAll && !!(hostElm && getHostRef(hostElm)?.$cmpMeta$.$flags$ & CMP_FLAGS.patchAll)) && parent.getRootNode().nodeType !== NODE_TYPES.DOCUMENT_FRAGMENT_NODE) patchSlottedNode(newNode);
2902
2990
  parent.insertBefore(newNode, reference);
2903
2991
  const { slotNode } = findSlotFromSlottedNode(newNode);
2904
- if (slotNode && !isInitialLoad) dispatchSlotChangeEvent(slotNode);
2992
+ if (slotNode) {
2993
+ if (isInitialLoad) initialSlotChanges.add(slotNode);
2994
+ else dispatchSlotChangeEvent(slotNode);
2995
+ }
2905
2996
  return newNode;
2906
2997
  }
2907
2998
  }
@@ -2957,6 +3048,7 @@ const renderVdom = (hostRef, renderFnResults, isInitialLoad = false) => {
2957
3048
  const oldVNode = hostRef.$vnode$ || newVNode(null, null);
2958
3049
  const rootVnode = isHost(renderFnResults) ? renderFnResults : h(null, null, renderFnResults);
2959
3050
  hostTagName = hostElm.tagName;
3051
+ hostRegistry = getHostRegistry(hostElm);
2960
3052
  if (BUILD.isDev && Array.isArray(renderFnResults) && renderFnResults.some(isHost)) throw new Error(`The <Host> must be the single root component.
2961
3053
  Looks like the render() function of "${hostTagName.toLowerCase()}" is returning an array that contains the <Host>.
2962
3054
 
@@ -3056,6 +3148,11 @@ render() {
3056
3148
  if (checkSlotFallbackVisibility) updateFallbackSlotVisibility(rootVnode.$elm$);
3057
3149
  plt.$flags$ &= ~PLATFORM_FLAGS.isTmpDisconnected;
3058
3150
  relocateNodes.length = 0;
3151
+ if (initialSlotChanges.size) {
3152
+ const slotNodes = [...initialSlotChanges];
3153
+ initialSlotChanges.clear();
3154
+ nextTick(() => slotNodes.forEach(dispatchSlotChangeEvent));
3155
+ }
3059
3156
  }
3060
3157
  if (BUILD.slotRelocation && !useNativeShadowDom && !(cmpMeta.$flags$ & CMP_FLAGS.shadowDomEncapsulation) && hostElm["s-cr"]) {
3061
3158
  const children = rootVnode.$elm$.__childNodes || rootVnode.$elm$.childNodes;
@@ -3109,11 +3206,12 @@ const markFirstConnected = (hostRef) => {
3109
3206
  * autoloader, where the ancestor tag may not be defined yet.
3110
3207
  *
3111
3208
  * @param ancestorElm the nearest Stencil ancestor element
3209
+ * @param registry the registry the waiting component is defined in
3112
3210
  */
3113
- const awaitAncestorConnected = async (ancestorElm) => {
3211
+ const awaitAncestorConnected = async (ancestorElm, registry) => {
3114
3212
  let ancestorHostRef = getHostRef(ancestorElm);
3115
3213
  if (!BUILD.lazyLoad && !ancestorHostRef) {
3116
- await getRegistry().whenDefined(ancestorElm.tagName.toLowerCase());
3214
+ await registry.whenDefined(ancestorElm.tagName.toLowerCase());
3117
3215
  ancestorHostRef = getHostRef(ancestorElm);
3118
3216
  }
3119
3217
  if (ancestorHostRef && !(ancestorHostRef.$flags$ & HOST_FLAGS.hasFiredConnected)) await ensureFirstConnectPromise(ancestorHostRef);
@@ -3469,8 +3567,7 @@ const initializeSignals = (elm, hostRef, cmpMeta) => {
3469
3567
  const instance = BUILD.lazyLoad ? hostRef.$lazyInstance$ : elm;
3470
3568
  for (const [memberName, [memberFlags]] of Object.entries(cmpMeta.$members$ ?? {})) {
3471
3569
  if (!(memberFlags & MEMBER_FLAGS.PropLike)) continue;
3472
- const initialVal = hostRef.$instanceValues$.get(memberName);
3473
- const sig = signal(initialVal);
3570
+ const sig = signal(hostRef.$instanceValues$.get(memberName));
3474
3571
  hostRef.$signalValues$.set(memberName, sig);
3475
3572
  let prevScheduleVal = sig.peek();
3476
3573
  disposers.push(effect(() => {
@@ -3598,9 +3695,7 @@ const h = (nodeName, vnodeData, ...children) => {
3598
3695
  if (classData && !(BUILD.vdomSignals && isSignalLike(classData))) vnodeData.class = typeof classData !== "object" ? classData : Object.keys(classData).filter((k) => classData[k]).join(" ");
3599
3696
  }
3600
3697
  }
3601
- if (BUILD.isDev && vNodeChildren.some(isHost)) consoleDevError(`The <Host> must be the single root component. Make sure:
3602
- - You are NOT using hostData() and <Host> in the same component.
3603
- - <Host> is used once, and it's the single root component of the render() function.`);
3698
+ if (BUILD.isDev && vNodeChildren.some(isHost)) consoleDevError(`The <Host> must be used once, and be the single root component of the render() function.`);
3604
3699
  if (BUILD.vdomFunctional && typeof nodeName === "function") return nodeName(vnodeData === null ? {} : vnodeData, vNodeChildren, vdomFnUtils);
3605
3700
  const vnode = newVNode(nodeName, null);
3606
3701
  vnode.$attrs$ = vnodeData;
@@ -3653,17 +3748,23 @@ const vdomFnUtils = {
3653
3748
  * Convert a {@link d.VNode} to a {@link d.ChildNode} in order to present a
3654
3749
  * friendlier public interface (hence, 'convertToPublic').
3655
3750
  *
3656
- * @param node the virtual DOM node to convert
3751
+ * Functional components receive primitive children unwrapped, so those
3752
+ * become text-only child nodes.
3753
+ *
3754
+ * @param node the virtual DOM node (or primitive child) to convert
3657
3755
  * @returns a converted child node
3658
3756
  */
3659
- const convertToPublic = (node) => ({
3757
+ const convertToPublic = (node) => typeof node !== "object" ? {
3758
+ vtag: null,
3759
+ vtext: String(node)
3760
+ } : {
3660
3761
  vattrs: node.$attrs$,
3661
3762
  vchildren: node.$children$,
3662
3763
  vkey: node.$key$,
3663
3764
  vname: node.$name$,
3664
3765
  vtag: node.$tag$,
3665
3766
  vtext: node.$text$
3666
- });
3767
+ };
3667
3768
  /**
3668
3769
  * Convert a {@link d.ChildNode} back to an equivalent {@link d.VNode} in
3669
3770
  * order to use the resulting object in the virtual DOM. The initial object was
@@ -3680,11 +3781,11 @@ const convertToPrivate = (node) => {
3680
3781
  if (node.vname) vnodeData.name = node.vname;
3681
3782
  return h(node.vtag, vnodeData, ...node.vchildren || []);
3682
3783
  }
3683
- const vnode = newVNode(node.vtag, node.vtext);
3684
- vnode.$attrs$ = node.vattrs;
3685
- vnode.$children$ = node.vchildren;
3686
- vnode.$key$ = node.vkey;
3687
- vnode.$name$ = node.vname;
3784
+ const vnode = newVNode(node.vtag ?? null, node.vtext);
3785
+ vnode.$attrs$ = node.vattrs ?? null;
3786
+ vnode.$children$ = node.vchildren ?? null;
3787
+ vnode.$key$ = node.vkey ?? null;
3788
+ vnode.$name$ = node.vname ?? null;
3688
3789
  return vnode;
3689
3790
  };
3690
3791
  /**
@@ -3804,7 +3905,7 @@ const initializeClientHydrate = (hostElm, tagName, hostId, hostRef) => {
3804
3905
  }
3805
3906
  addSlotRelocateNode(siNode, siSlot, false, siNode["s-oo"] || currentPos);
3806
3907
  if (siNode.parentElement?.shadowRoot && siNode["getAttribute"] && siNode.getAttribute("slot")) siNode.removeAttribute("slot");
3807
- if (BUILD.lightDomPatches || BUILD.slotChildNodes || BUILD.patchAll && hostRef.$cmpMeta$.$flags$ & CMP_FLAGS.patchAll) patchSlottedNode(siNode);
3908
+ if (BUILD.lightDomPatches || BUILD.slotChildNodes || BUILD.patchAll && hostRef.$cmpMeta$.$flags$ & CMP_FLAGS.patchAll) patchSsrSlottedNode(siNode);
3808
3909
  }
3809
3910
  currentPos = (siNode["s-oo"] || currentPos) + 1;
3810
3911
  }
@@ -3982,6 +4083,7 @@ const initializeDocumentHydrate = (node, orgLocNodes) => {
3982
4083
  const createSimpleVNode = (vnode) => ({
3983
4084
  $flags$: 0,
3984
4085
  $index$: "0",
4086
+ $children$: null,
3985
4087
  ...vnode
3986
4088
  });
3987
4089
  function addSlot(slotName, slotId, childVNode, node, parentVNode, childRenderNodes, slotNodes, shadowRootNodes, slottedNodes) {
@@ -4365,7 +4467,7 @@ const scopeSelector = (selector, scopeSelectorText, hostSelector, slotSelector)
4365
4467
  else return shallowPart.trim();
4366
4468
  }).join(", ");
4367
4469
  };
4368
- const isScopableAtRule = (selector) => selector.startsWith("@media") || selector.startsWith("@supports") || selector.startsWith("@page") || selector.startsWith("@document") || selector.startsWith("@layer");
4470
+ const isScopableAtRule = (selector) => selector.startsWith("@media") || selector.startsWith("@supports") || selector.startsWith("@page") || selector.startsWith("@document") || selector.startsWith("@layer") || selector.startsWith("@container");
4369
4471
  const scopeSelectors = (cssText, scopeSelectorText, hostSelector, slotSelector, commentOriginalSelector) => {
4370
4472
  return processRules(cssText, (rule) => {
4371
4473
  let selector = rule.selector;
@@ -4484,7 +4586,7 @@ const scopeCss = (cssText, scopeId, commentOriginalSelector) => {
4484
4586
  };
4485
4587
  //#endregion
4486
4588
  //#region src/runtime/mode.ts
4487
- const computeMode = (elm) => modeResolutionChain.map((h) => h(elm)).find((m) => !!m);
4589
+ const computeMode = (elm) => modeResolver.map((h) => h(elm)).find((m) => !!m);
4488
4590
  const getMode = (ref) => getHostRef(ref)?.$modeName$;
4489
4591
  //#endregion
4490
4592
  //#region src/runtime/normalize-watchers.ts
@@ -4549,23 +4651,14 @@ const normalizeWatchers = (raw) => {
4549
4651
  *
4550
4652
  * @param propValue the new value to coerce to some type
4551
4653
  * @param propType the type of the prop, expressed as a binary number
4552
- * @param isFormAssociated whether the component is form-associated (optional)
4553
4654
  * @returns the parsed/coerced value
4554
4655
  */
4555
- const parsePropertyValue = (propValue, propType, isFormAssociated) => {
4656
+ const parsePropertyValue = (propValue, propType) => {
4556
4657
  if (propValue != null && !isComplexType(propValue)) {
4557
4658
  /**
4558
4659
  * ensure this value is of the correct prop type
4559
4660
  */
4560
- if (BUILD.propBoolean && propType & MEMBER_FLAGS.Boolean) {
4561
- /**
4562
- * For form-associated components, according to HTML spec, the presence of any boolean attribute
4563
- * (regardless of its value, even "false") should make the property true.
4564
- * For non-form-associated components, we maintain the legacy behavior where "false" becomes false.
4565
- */
4566
- if (BUILD.formAssociated && isFormAssociated && typeof propValue === "string") return propValue === "" || !!propValue;
4567
- else return propValue === "false" ? false : propValue === "" || !!propValue;
4568
- }
4661
+ if (BUILD.propBoolean && propType & MEMBER_FLAGS.Boolean) return propValue === "" || !!propValue;
4569
4662
  /**
4570
4663
  * force it to be a number
4571
4664
  */
@@ -4607,7 +4700,7 @@ const setValue = (ref, propName, newVal, cmpMeta) => {
4607
4700
  if (BUILD.signalBacking) {
4608
4701
  const sig = hostRef?.$signalValues$?.get(propName);
4609
4702
  if (sig !== void 0) {
4610
- const parsed = parsePropertyValue(newVal, cmpMeta.$members$[propName][0], BUILD.formAssociated && !!(cmpMeta.$flags$ & CMP_FLAGS.formAssociated));
4703
+ const parsed = parsePropertyValue(newVal, cmpMeta.$members$[propName][0]);
4611
4704
  if (BUILD.serializer && BUILD.reflect && cmpMeta.$attrsToReflect$ && cmpMeta.$serializers$?.[propName]) {
4612
4705
  const elm = BUILD.lazyLoad ? hostRef.$hostElement$ : ref;
4613
4706
  applySerializers(hostRef, cmpMeta, propName, parsed, BUILD.lazyLoad ? hostRef.$lazyInstance$ : elm);
@@ -4625,7 +4718,7 @@ const setValue = (ref, propName, newVal, cmpMeta) => {
4625
4718
  const oldVal = hostRef.$instanceValues$.get(propName);
4626
4719
  const flags = hostRef.$flags$;
4627
4720
  const instance = BUILD.lazyLoad ? hostRef.$lazyInstance$ : elm;
4628
- newVal = parsePropertyValue(newVal, cmpMeta.$members$[propName][0], BUILD.formAssociated && !!(cmpMeta.$flags$ & CMP_FLAGS.formAssociated));
4721
+ newVal = parsePropertyValue(newVal, cmpMeta.$members$[propName][0]);
4629
4722
  const didValueChange = newVal !== oldVal && !(Number.isNaN(oldVal) && Number.isNaN(newVal));
4630
4723
  if ((!BUILD.lazyLoad || !(flags & HOST_FLAGS.isConstructingInstance) || oldVal === void 0) && didValueChange) {
4631
4724
  hostRef.$instanceValues$.set(propName, newVal);
@@ -4674,6 +4767,22 @@ const setValue = (ref, propName, newVal, cmpMeta) => {
4674
4767
  */
4675
4768
  const reflectedAttrValue = (propValue) => propValue == null || propValue === false ? null : propValue === true ? "" : String(propValue);
4676
4769
  /**
4770
+ * Hand values written to a lazy component's element before its instance existed to the
4771
+ * instance's own `@Prop` setters. Must run as soon as the instance is constructed, so that
4772
+ * whenever `$lazyInstance$` is set, reads through it agree with the element's last write.
4773
+ *
4774
+ * @param hostRef the runtime bookkeeping object of a freshly constructed lazy instance
4775
+ * @param cmpMeta runtime metadata for the component (with any run-time only setters flagged)
4776
+ */
4777
+ const replayPendingSetterValues = (hostRef, cmpMeta) => {
4778
+ const instance = hostRef.$lazyInstance$;
4779
+ if (!instance) return;
4780
+ for (const [memberName, [memberFlags]] of Object.entries(cmpMeta.$members$ ?? {})) if (memberFlags & MEMBER_FLAGS.Setter && hostRef.$instanceValues$.has(memberName)) {
4781
+ const pendingValue = hostRef.$instanceValues$.get(memberName);
4782
+ if (instance[memberName] !== pendingValue) instance[memberName] = pendingValue;
4783
+ }
4784
+ };
4785
+ /**
4677
4786
  * Attach a series of runtime constructs to a compiled Stencil component
4678
4787
  * constructor, including getters and setters for the `@Prop` and `@State`
4679
4788
  * decorators, callbacks for when attributes change, and so on.
@@ -4730,9 +4839,8 @@ const proxyComponent = (Cstr, cmpMeta, flags) => {
4730
4839
  if (BUILD.lazyLoad) {
4731
4840
  if ((cmpMeta.$members$[memberName][0] & MEMBER_FLAGS.Getter) === 0) return getValue(this, memberName);
4732
4841
  const ref = getHostRef(this);
4733
- const instance = ref ? ref.$lazyInstance$ : prototype;
4734
- if (!instance) return;
4735
- return instance[memberName];
4842
+ if (!ref) return prototype[memberName];
4843
+ return ref.$lazyInstance$ ? ref.$lazyInstance$[memberName] : getValue(this, memberName);
4736
4844
  }
4737
4845
  if (!BUILD.lazyLoad) return origGetter ? origGetter.apply(this) : getValue(this, memberName);
4738
4846
  },
@@ -4747,7 +4855,7 @@ const proxyComponent = (Cstr, cmpMeta, flags) => {
4747
4855
  }
4748
4856
  if (origSetter) {
4749
4857
  if (typeof (memberFlags & MEMBER_FLAGS.State ? this[memberName] : ref.$hostElement$[memberName]) === "undefined" && ref.$instanceValues$.get(memberName)) newValue = ref.$instanceValues$.get(memberName);
4750
- origSetter.apply(this, [parsePropertyValue(newValue, memberFlags, BUILD.formAssociated && !!(cmpMeta.$flags$ & CMP_FLAGS.formAssociated))]);
4858
+ origSetter.apply(this, [parsePropertyValue(newValue, memberFlags)]);
4751
4859
  newValue = memberFlags & MEMBER_FLAGS.State ? this[memberName] : ref.$hostElement$[memberName];
4752
4860
  setValue(this, memberName, newValue, cmpMeta);
4753
4861
  return;
@@ -4759,21 +4867,15 @@ const proxyComponent = (Cstr, cmpMeta, flags) => {
4759
4867
  if (BUILD.lazyLoad) {
4760
4868
  if ((flags & PROXY_FLAGS.isElementConstructor) === 0 || (cmpMeta.$members$[memberName][0] & MEMBER_FLAGS.Setter) === 0) {
4761
4869
  setValue(this, memberName, newValue, cmpMeta);
4762
- if (flags & PROXY_FLAGS.isElementConstructor && !ref.$lazyInstance$) ref.$fetchedCbList$.push(() => {
4763
- if (cmpMeta.$members$[memberName][0] & MEMBER_FLAGS.Setter && ref.$lazyInstance$[memberName] !== ref.$instanceValues$.get(memberName)) ref.$lazyInstance$[memberName] = newValue;
4764
- });
4765
4870
  return;
4766
4871
  }
4767
- const setterSetVal = () => {
4872
+ const parsedValue = parsePropertyValue(newValue, memberFlags);
4873
+ if (ref.$lazyInstance$) {
4768
4874
  const currentValue = ref.$lazyInstance$[memberName];
4769
4875
  if (!ref.$instanceValues$.get(memberName) && currentValue) ref.$instanceValues$.set(memberName, currentValue);
4770
- ref.$lazyInstance$[memberName] = parsePropertyValue(newValue, memberFlags, BUILD.formAssociated && !!(cmpMeta.$flags$ & CMP_FLAGS.formAssociated));
4876
+ ref.$lazyInstance$[memberName] = parsedValue;
4771
4877
  setValue(this, memberName, ref.$lazyInstance$[memberName], cmpMeta);
4772
- };
4773
- if (ref.$lazyInstance$) setterSetVal();
4774
- else ref.$fetchedCbList$.push(() => {
4775
- setterSetVal();
4776
- });
4878
+ } else ref.$instanceValues$.set(memberName, parsedValue);
4777
4879
  }
4778
4880
  } });
4779
4881
  } else if (BUILD.lazyLoad && BUILD.method && flags & PROXY_FLAGS.isElementConstructor && memberFlags & MEMBER_FLAGS.Method) Object.defineProperty(prototype, memberName, { value(...args) {
@@ -4825,7 +4927,10 @@ const proxyComponent = (Cstr, cmpMeta, flags) => {
4825
4927
  const isBooleanTarget = propMemberFlags & MEMBER_FLAGS.Boolean;
4826
4928
  if (BUILD.reflect && propMemberFlags & MEMBER_FLAGS.ReflectAttr && propMemberFlags & MEMBER_FLAGS.Any && !isComplexType(this[propName]) && reflectedAttrValue(this[propName]) === newValue) return;
4827
4929
  const isSpuriousBooleanRemoval = isBooleanTarget && newValue === null && this[propName] === void 0;
4828
- if (isBooleanTarget) newValue = !(newValue === null || newValue === "false");
4930
+ if (isBooleanTarget) {
4931
+ if (BUILD.isDev && newValue === "false") consoleDevWarn(`<${cmpMeta.$tagName$} ${attrName}="false">: boolean attributes are true when present, regardless of value. Remove the attribute or set the "${propName}" property to false instead.`);
4932
+ newValue = newValue !== null;
4933
+ }
4829
4934
  const propDesc = Object.getOwnPropertyDescriptor(prototype, propName);
4830
4935
  if (!isSpuriousBooleanRemoval && newValue != this[propName] && (!propDesc.get || !!propDesc.set)) this[propName] = newValue;
4831
4936
  });
@@ -4888,9 +4993,12 @@ const initializeComponent = async (elm, hostRef, cmpMeta, hmrVersionId) => {
4888
4993
  } catch (e) {
4889
4994
  consoleError(e, elm);
4890
4995
  }
4891
- if (BUILD.member) hostRef.$flags$ &= ~HOST_FLAGS.isConstructingInstance;
4996
+ if (BUILD.member) {
4997
+ hostRef.$flags$ &= ~HOST_FLAGS.isConstructingInstance;
4998
+ replayPendingSetterValues(hostRef, cmpMeta);
4999
+ }
4892
5000
  endNewInstance();
4893
- if (BUILD.asyncLoading && hostRef.$ancestorComponent$) await awaitAncestorConnected(hostRef.$ancestorComponent$);
5001
+ if (BUILD.asyncLoading && hostRef.$ancestorComponent$) await awaitAncestorConnected(hostRef.$ancestorComponent$, getHostRegistry(elm));
4894
5002
  if (!(BUILD.slotRelocation && cmpMeta.$flags$ & CMP_FLAGS.hasSlotRelocation)) {
4895
5003
  fireConnectedCallback(hostRef.$lazyInstance$, elm);
4896
5004
  if (BUILD.asyncLoading) markFirstConnected(hostRef);
@@ -4990,9 +5098,16 @@ const connectedCallback = (elm) => {
4990
5098
  }
4991
5099
  if (BUILD.asyncLoading) {
4992
5100
  let ancestorComponent = elm;
4993
- while (ancestorComponent = ancestorComponent.parentNode || ancestorComponent.host) if (BUILD.hydrateClientSide && ancestorComponent.nodeType === NODE_TYPE.ElementNode && ancestorComponent.hasAttribute("s-id") && ancestorComponent["s-p"] || ancestorComponent["s-p"]) {
4994
- attachToAncestor(hostRef, hostRef.$ancestorComponent$ = ancestorComponent);
4995
- break;
5101
+ while (ancestorComponent = ancestorComponent.parentNode || ancestorComponent.host) {
5102
+ if (BUILD.hydrateClientSide && !ancestorComponent["s-p"] && ancestorComponent.nodeType === NODE_TYPE.ElementNode && ancestorComponent.hasAttribute("s-id")) {
5103
+ ancestorComponent["s-p"] = [];
5104
+ ancestorComponent["s-rc"] = [];
5105
+ ancestorComponent["s-pc"] = [];
5106
+ }
5107
+ if (ancestorComponent["s-p"]) {
5108
+ attachToAncestor(hostRef, hostRef.$ancestorComponent$ = ancestorComponent);
5109
+ break;
5110
+ }
4996
5111
  }
4997
5112
  }
4998
5113
  if (BUILD.prop && !BUILD.hydrateServerSide && cmpMeta.$members$) Object.entries(cmpMeta.$members$).map(([memberName, [memberFlags]]) => {
@@ -5108,48 +5223,45 @@ const hmrStandalone = async (hostElement, cmpMeta, hmrVersionId) => {
5108
5223
  `${modulePath}?s-hmr=${hmrVersionId}`
5109
5224
  );
5110
5225
  const NewClass = Object.values(newModule).find((v) => typeof v === "function" && v.is === cmpMeta.$tagName$) ?? newModule.default;
5111
- if (!NewClass) return;
5112
- const ctor = customElements.get(cmpMeta.$tagName$);
5113
- if (ctor) {
5114
- for (const key of Object.getOwnPropertyNames(NewClass.prototype)) {
5115
- if (key === "constructor") continue;
5116
- Object.defineProperty(ctor.prototype, key, Object.getOwnPropertyDescriptor(NewClass.prototype, key));
5117
- }
5118
- const styleDesc = Object.getOwnPropertyDescriptor(NewClass, "style");
5119
- if (styleDesc) {
5120
- Object.defineProperty(ctor, "style", styleDesc);
5121
- const newStyle = NewClass.style;
5122
- if (newStyle) {
5123
- const scopeId = getScopeId(cmpMeta);
5124
- const isShadow = !!(cmpMeta.$flags$ & CMP_FLAGS.shadowDomEncapsulation);
5125
- console.log("[stencil-hmr] registerStyle", {
5126
- tag: cmpMeta.$tagName$,
5127
- scopeId,
5128
- isShadow,
5129
- cssLen: newStyle.length
5130
- });
5131
- registerStyle(scopeId, newStyle, isShadow);
5132
- }
5133
- }
5134
- }
5135
- const isShadow = !!(cmpMeta.$flags$ & CMP_FLAGS.shadowDomEncapsulation);
5136
- document.querySelectorAll(cmpMeta.$tagName$).forEach((el) => {
5137
- const hostRef = getHostRef(el);
5138
- if (BUILD.hostListener && hostRef?.$rmListeners$) {
5139
- hostRef.$rmListeners$.map((rmListener) => rmListener());
5140
- hostRef.$rmListeners$ = void 0;
5141
- addHostEventListeners(el, hostRef, cmpMeta.$listeners$);
5142
- }
5143
- if (!isShadow && hostRef) {
5144
- console.log("[stencil-hmr] calling attachStyles for", cmpMeta.$tagName$);
5145
- attachStyles(hostRef);
5146
- }
5147
- forceUpdate(el);
5148
- });
5226
+ if (NewClass) hmrApplyClass(cmpMeta, NewClass);
5149
5227
  } catch (e) {
5150
5228
  console.error(`[Stencil HMR] Failed to reload <${cmpMeta.$tagName$}>`, e);
5151
5229
  }
5152
5230
  };
5231
+ /**
5232
+ * Patch a re-executed component class onto the registered one and re-render every live instance.
5233
+ * Shared by the standalone re-import above and bundlers that re-execute the module themselves
5234
+ * (webpack/rspack `module.hot`), which reach it via the constructor's `s-hmr-apply` hook.
5235
+ *
5236
+ * @param cmpMeta runtime metadata for the component
5237
+ * @param NewClass the component's newly executed class
5238
+ */
5239
+ const hmrApplyClass = (cmpMeta, NewClass) => {
5240
+ const ctor = customElements.get(cmpMeta.$tagName$);
5241
+ const isShadow = !!(cmpMeta.$flags$ & CMP_FLAGS.shadowDomEncapsulation);
5242
+ if (ctor && ctor !== NewClass) {
5243
+ for (const key of Object.getOwnPropertyNames(NewClass.prototype)) {
5244
+ if (key === "constructor") continue;
5245
+ Object.defineProperty(ctor.prototype, key, Object.getOwnPropertyDescriptor(NewClass.prototype, key));
5246
+ }
5247
+ const styleDesc = Object.getOwnPropertyDescriptor(NewClass, "style");
5248
+ if (styleDesc) {
5249
+ Object.defineProperty(ctor, "style", styleDesc);
5250
+ const newStyle = NewClass.style;
5251
+ if (newStyle) registerStyle(getScopeId(cmpMeta), newStyle, isShadow);
5252
+ }
5253
+ }
5254
+ document.querySelectorAll(cmpMeta.$tagName$).forEach((el) => {
5255
+ const hostRef = getHostRef(el);
5256
+ if (BUILD.hostListener && hostRef?.$rmListeners$) {
5257
+ hostRef.$rmListeners$.map((rmListener) => rmListener());
5258
+ hostRef.$rmListeners$ = void 0;
5259
+ addHostEventListeners(el, hostRef, cmpMeta.$listeners$);
5260
+ }
5261
+ if (!isShadow && hostRef) attachStyles(hostRef);
5262
+ forceUpdate(el);
5263
+ });
5264
+ };
5153
5265
  //#endregion
5154
5266
  //#region src/runtime/bootstrap-loader.ts
5155
5267
  const bootstrapLazy = (lazyBundles, options = {}) => {
@@ -5567,8 +5679,8 @@ const insertChildVNodeAnnotations = (doc, vnodeChild, cmpData, hostId, depth, in
5567
5679
  //#endregion
5568
5680
  //#region src/testing/platform/index.ts
5569
5681
  const setMode = (handler) => {
5570
- modeResolutionChain.length = 0;
5571
- modeResolutionChain.push(handler);
5682
+ modeResolver.length = 0;
5683
+ modeResolver.push(handler);
5572
5684
  };
5573
5685
  const needsScopedSSR = () => scopedSSR;
5574
5686
  let scopedSSR = false;
@@ -5647,79 +5759,6 @@ const buildEvents = () => {
5647
5759
  };
5648
5760
  };
5649
5761
  //#endregion
5650
- //#region src/compiler/app-core/app-data.ts
5651
- /**
5652
- * Generate a {@link BuildFeatures} entity, based on the provided component metadata
5653
- * @param cmps a collection of component compiler metadata, used to set values on the generated build features object
5654
- * @returns the generated build features entity
5655
- */
5656
- const getBuildFeatures = (cmps) => {
5657
- const slot = cmps.some((c) => c.htmlTagNames.includes("slot"));
5658
- const shadowDom = cmps.some((c) => c.encapsulation === "shadow");
5659
- const slotRelocation = cmps.some((c) => c.encapsulation !== "shadow" && c.htmlTagNames.includes("slot"));
5660
- const f = {
5661
- allRenderFn: cmps.every((c) => c.hasRenderFn),
5662
- formAssociated: cmps.some((c) => c.formAssociated),
5663
- deserializer: cmps.some((c) => c.hasDeserializer),
5664
- element: cmps.some((c) => c.hasElement),
5665
- event: cmps.some((c) => c.hasEvent),
5666
- hasRenderFn: cmps.some((c) => c.hasRenderFn),
5667
- lifecycle: cmps.some((c) => c.hasLifecycle),
5668
- asyncLoading: true,
5669
- hostListener: cmps.some((c) => c.hasListener),
5670
- hostListenerTargetWindow: cmps.some((c) => c.hasListenerTargetWindow),
5671
- hostListenerTargetDocument: cmps.some((c) => c.hasListenerTargetDocument),
5672
- hostListenerTargetBody: cmps.some((c) => c.hasListenerTargetBody),
5673
- hostListenerTarget: cmps.some((c) => c.hasListenerTarget),
5674
- member: cmps.some((c) => c.hasMember),
5675
- method: cmps.some((c) => c.hasMethod),
5676
- mode: cmps.some((c) => c.hasMode),
5677
- observeAttribute: cmps.some((c) => c.hasAttribute || c.hasWatchCallback || c.hasDeserializer),
5678
- prop: cmps.some((c) => c.hasProp),
5679
- propBoolean: cmps.some((c) => c.hasPropBoolean),
5680
- propChangeCallback: cmps.some((c) => c.hasWatchCallback || c.hasDeserializer || c.hasSerializer),
5681
- propNumber: cmps.some((c) => c.hasPropNumber),
5682
- propString: cmps.some((c) => c.hasPropString),
5683
- propMutable: cmps.some((c) => c.hasPropMutable),
5684
- reflect: cmps.some((c) => c.hasReflect || c.hasSerializer),
5685
- scoped: cmps.some((c) => c.encapsulation === "scoped"),
5686
- serializer: cmps.some((c) => c.hasSerializer),
5687
- shadowDom,
5688
- shadowDelegatesFocus: shadowDom && cmps.some((c) => c.shadowDelegatesFocus),
5689
- shadowModeClosed: shadowDom && cmps.some((c) => c.shadowMode === "closed"),
5690
- shadowSlotAssignmentManual: shadowDom && cmps.some((c) => c.slotAssignment === "manual"),
5691
- shadowClonable: shadowDom && cmps.some((c) => c.shadowClonable),
5692
- shadowSerializable: shadowDom && cmps.some((c) => c.shadowSerializable),
5693
- slot,
5694
- slotRelocation,
5695
- state: cmps.some((c) => c.hasState),
5696
- style: cmps.some((c) => c.hasStyle),
5697
- svg: cmps.some((c) => c.htmlTagNames.includes("svg")),
5698
- updatable: cmps.some((c) => c.isUpdateable),
5699
- vdomAttribute: cmps.some((c) => c.hasVdomAttribute),
5700
- vdomXlink: cmps.some((c) => c.hasVdomXlink),
5701
- vdomClass: cmps.some((c) => c.hasVdomClass),
5702
- vdomFunctional: cmps.some((c) => c.hasVdomFunctional),
5703
- vdomKey: cmps.some((c) => c.hasVdomKey),
5704
- vdomListener: cmps.some((c) => c.hasVdomListener),
5705
- vdomPropOrAttr: cmps.some((c) => c.hasVdomPropOrAttr),
5706
- vdomPropOrAttrPrefix: cmps.some((c) => c.hasVdomPropOrAttrPrefix),
5707
- vdomRef: cmps.some((c) => c.hasVdomRef),
5708
- vdomRender: cmps.some((c) => c.hasVdomRender),
5709
- vdomStyle: cmps.some((c) => c.hasVdomStyle),
5710
- vdomText: cmps.some((c) => c.hasVdomText),
5711
- vdomSignals: cmps.some((c) => c.hasSignalsImport),
5712
- taskQueue: true,
5713
- patchAll: cmps.some((c) => c.hasPatchAll),
5714
- patchChildren: cmps.some((c) => c.hasPatchChildren),
5715
- patchClone: cmps.some((c) => c.hasPatchClone),
5716
- patchInsert: cmps.some((c) => c.hasPatchInsert)
5717
- };
5718
- f.vdomAttribute = f.vdomAttribute || f.reflect;
5719
- f.vdomPropOrAttr = f.vdomPropOrAttr || f.reflect;
5720
- return f;
5721
- };
5722
- //#endregion
5723
5762
  //#region src/compiler/sys/resolve/resolve-utils.ts
5724
5763
  const getModuleId = (orgImport) => {
5725
5764
  if (orgImport.startsWith("~")) orgImport = orgImport.substring(1);
@@ -5809,6 +5848,92 @@ const createCustomResolverAsync = (sys, inMemoryFs, exts) => {
5809
5848
  extensions: exts
5810
5849
  };
5811
5850
  };
5851
+ //#endregion
5852
+ //#region src/compiler/app-core/app-data.ts
5853
+ /**
5854
+ * Generate a {@link BuildFeatures} entity, based on the provided component metadata
5855
+ * @param cmps a collection of component compiler metadata, used to set values on the generated build features object
5856
+ * @returns the generated build features entity
5857
+ */
5858
+ const getBuildFeatures = (cmps) => {
5859
+ const slot = cmps.some((c) => c.htmlTagNames.includes("slot"));
5860
+ const shadowDom = cmps.some((c) => c.encapsulation === "shadow");
5861
+ const slotRelocation = cmps.some((c) => c.encapsulation !== "shadow" && c.htmlTagNames.includes("slot"));
5862
+ const f = {
5863
+ allRenderFn: cmps.every((c) => c.hasRenderFn),
5864
+ formAssociated: cmps.some((c) => c.formAssociated),
5865
+ deserializer: cmps.some((c) => c.hasDeserializer),
5866
+ element: cmps.some((c) => c.hasElement),
5867
+ event: cmps.some((c) => c.hasEvent),
5868
+ hasRenderFn: cmps.some((c) => c.hasRenderFn),
5869
+ lifecycle: cmps.some((c) => c.hasLifecycle),
5870
+ asyncLoading: true,
5871
+ hostListener: cmps.some((c) => c.hasListener),
5872
+ hostListenerTargetWindow: cmps.some((c) => c.hasListenerTargetWindow),
5873
+ hostListenerTargetDocument: cmps.some((c) => c.hasListenerTargetDocument),
5874
+ hostListenerTargetBody: cmps.some((c) => c.hasListenerTargetBody),
5875
+ hostListenerTarget: cmps.some((c) => c.hasListenerTarget),
5876
+ member: cmps.some((c) => c.hasMember),
5877
+ method: cmps.some((c) => c.hasMethod),
5878
+ mode: cmps.some((c) => c.hasMode),
5879
+ observeAttribute: cmps.some((c) => c.hasAttribute || c.hasWatchCallback || c.hasDeserializer),
5880
+ prop: cmps.some((c) => c.hasProp),
5881
+ propBoolean: cmps.some((c) => c.hasPropBoolean),
5882
+ propChangeCallback: cmps.some((c) => c.hasWatchCallback || c.hasDeserializer || c.hasSerializer),
5883
+ propNumber: cmps.some((c) => c.hasPropNumber),
5884
+ propString: cmps.some((c) => c.hasPropString),
5885
+ propMutable: cmps.some((c) => c.hasPropMutable),
5886
+ reflect: cmps.some((c) => c.hasReflect || c.hasSerializer),
5887
+ scoped: cmps.some((c) => c.encapsulation === "scoped"),
5888
+ serializer: cmps.some((c) => c.hasSerializer),
5889
+ shadowDom,
5890
+ shadowDelegatesFocus: shadowDom && cmps.some((c) => c.shadowDelegatesFocus),
5891
+ shadowModeClosed: shadowDom && cmps.some((c) => c.shadowMode === "closed"),
5892
+ shadowSlotAssignmentManual: shadowDom && cmps.some((c) => c.slotAssignment === "manual"),
5893
+ shadowClonable: shadowDom && cmps.some((c) => c.shadowClonable),
5894
+ shadowSerializable: shadowDom && cmps.some((c) => c.shadowSerializable),
5895
+ slot,
5896
+ slotRelocation,
5897
+ state: cmps.some((c) => c.hasState),
5898
+ style: cmps.some((c) => c.hasStyle),
5899
+ svg: cmps.some((c) => c.htmlTagNames.includes("svg")),
5900
+ updatable: cmps.some((c) => c.isUpdateable),
5901
+ vdomAttribute: cmps.some((c) => c.hasVdomAttribute),
5902
+ vdomXlink: cmps.some((c) => c.hasVdomXlink),
5903
+ vdomClass: cmps.some((c) => c.hasVdomClass),
5904
+ vdomFunctional: cmps.some((c) => c.hasVdomFunctional),
5905
+ vdomKey: cmps.some((c) => c.hasVdomKey),
5906
+ vdomListener: cmps.some((c) => c.hasVdomListener),
5907
+ vdomPropOrAttr: cmps.some((c) => c.hasVdomPropOrAttr),
5908
+ vdomPropOrAttrPrefix: cmps.some((c) => c.hasVdomPropOrAttrPrefix),
5909
+ vdomRef: cmps.some((c) => c.hasVdomRef),
5910
+ vdomRender: cmps.some((c) => c.hasVdomRender),
5911
+ vdomStyle: cmps.some((c) => c.hasVdomStyle),
5912
+ vdomText: cmps.some((c) => c.hasVdomText),
5913
+ vdomSignals: cmps.some((c) => c.hasSignalsImport),
5914
+ taskQueue: true,
5915
+ patchAll: cmps.some((c) => c.hasPatchAll),
5916
+ patchChildren: cmps.some((c) => c.hasPatchChildren),
5917
+ patchClone: cmps.some((c) => c.hasPatchClone),
5918
+ patchInsert: cmps.some((c) => c.hasPatchInsert)
5919
+ };
5920
+ f.vdomAttribute = f.vdomAttribute || f.reflect;
5921
+ f.vdomPropOrAttr = f.vdomPropOrAttr || f.reflect;
5922
+ return f;
5923
+ };
5924
+ //#endregion
5925
+ //#region src/compiler/style/component-global-styles.ts
5926
+ /**
5927
+ * Match `@import` of a `stencil-*` virtual import in any form CSS allows or a preprocessor emits:
5928
+ * quoted or not, bare or `url()`-wrapped, and with or without whitespace after `@import` (Sass's
5929
+ * compressed output drops it). Capture group 2 holds any trailing modifiers, e.g. `layer(name)`.
5930
+ * @param name the virtual import to match
5931
+ * @returns a global regex
5932
+ */
5933
+ const stencilVirtualImportRe = (name) => new RegExp(`@import(?:\\s+|(?=['"]|url\\())(?:url\\(\\s*)?(['"]?)${name}(?![\\w-])\\1\\s*\\)?([^;]*);?`, "g");
5934
+ stencilVirtualImportRe("stencil-component-globals");
5935
+ stencilVirtualImportRe("stencil-hydrate");
5936
+ stencilVirtualImportRe("stencil-css-components");
5812
5937
  new RegExp(`^(${[.../* @__PURE__ */ new Set([
5813
5938
  "child_process",
5814
5939
  "cluster",
@@ -7357,15 +7482,6 @@ const createSystem = (c) => {
7357
7482
  }
7358
7483
  return results;
7359
7484
  };
7360
- /**
7361
- * `self` is the global namespace object used within a web worker.
7362
- * `window` is the browser's global namespace object (I reorganized this to check the reference on that second)
7363
- * `global` is Node's global namespace object. https://nodejs.org/api/globals.html#globals_global
7364
- *
7365
- * loading in this order should allow workers, which are most common, then browser,
7366
- * then Node to grab the reference to fetch correctly.
7367
- */
7368
- const fetch = typeof self !== "undefined" ? self?.fetch : typeof window !== "undefined" ? window?.fetch : typeof global !== "undefined" ? global?.fetch : void 0;
7369
7485
  const writeFile = async (p, data) => writeFileSync(p, data);
7370
7486
  const tmpDirSync = () => "/.tmp";
7371
7487
  const tick = Promise.resolve();
@@ -7376,6 +7492,7 @@ const createSystem = (c) => {
7376
7492
  if (typeof hashLength === "number") hashHex = hashHex.slice(0, hashLength);
7377
7493
  return hashHex;
7378
7494
  };
7495
+ const generateFileHash = async (filePath, hashLength) => generateContentHash(readFileSync(filePath), hashLength);
7379
7496
  const copy = async (copyTasks, srcDir) => {
7380
7497
  const results = {
7381
7498
  diagnostics: [],
@@ -7385,9 +7502,6 @@ const createSystem = (c) => {
7385
7502
  logger.info("todo, copy task", copyTasks.length, srcDir);
7386
7503
  return results;
7387
7504
  };
7388
- const getEnvironmentVar = (key) => {
7389
- return process$1?.env[key];
7390
- };
7391
7505
  const getLocalModulePath = (opts) => join(opts.rootDir, "node_modules", opts.moduleId, opts.path);
7392
7506
  const getRemoteModuleUrl = (opts) => {
7393
7507
  const npmBaseUrl = "https://cdn.jsdelivr.net/npm/";
@@ -7403,13 +7517,14 @@ const createSystem = (c) => {
7403
7517
  access,
7404
7518
  accessSync,
7405
7519
  addDestroy,
7520
+ checkVersion: async () => noop,
7406
7521
  copyFile,
7407
7522
  createDir,
7408
7523
  createDirSync,
7409
7524
  homeDir,
7410
7525
  isTTY,
7411
- getEnvironmentVar,
7412
7526
  destroy,
7527
+ dynamicImport: (p) => import(p),
7413
7528
  encodeToBase64,
7414
7529
  exit: async (exitCode) => logger.warn(`exit ${exitCode}`),
7415
7530
  getCurrentDirectory,
@@ -7420,6 +7535,7 @@ const createSystem = (c) => {
7420
7535
  isSymbolicLink,
7421
7536
  nextTick,
7422
7537
  normalizePath: normalize,
7538
+ onProcessInterrupt: noop,
7423
7539
  platformPath: path,
7424
7540
  readDir,
7425
7541
  readDirSync,
@@ -7429,7 +7545,6 @@ const createSystem = (c) => {
7429
7545
  realpathSync,
7430
7546
  removeDestroy,
7431
7547
  rename,
7432
- fetch,
7433
7548
  resolvePath,
7434
7549
  removeDir,
7435
7550
  removeDirSync,
@@ -7444,6 +7559,7 @@ const createSystem = (c) => {
7444
7559
  writeFile,
7445
7560
  writeFileSync,
7446
7561
  generateContentHash,
7562
+ generateFileHash,
7447
7563
  createWorkerController: null,
7448
7564
  details: {
7449
7565
  cpuModel: "",