@stencil/core 5.0.0-beta.30 → 5.0.0-beta.32

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.
@@ -972,6 +972,7 @@ const patchSlotAppendChild = (HostElementPrototype) => {
972
972
  const { slotName, slotNode } = findSlotFromSlottedNode(newChild, this);
973
973
  if (slotNode) {
974
974
  addSlotRelocateNode(newChild, slotNode);
975
+ patchSlottedNode(newChild);
975
976
  const slotChildNodes = getSlotChildSiblings(slotNode, slotName);
976
977
  const appendAfter = slotChildNodes[slotChildNodes.length - 1];
977
978
  const insertedNode = internalCall(internalCall(appendAfter, "parentNode"), "insertBefore")(newChild, appendAfter.nextSibling);
@@ -994,8 +995,10 @@ const patchSlotRemoveChild = (ElementPrototype) => {
994
995
  ElementPrototype.__removeChild = ElementPrototype.removeChild;
995
996
  ElementPrototype.removeChild = function(toRemove) {
996
997
  if (toRemove && typeof toRemove["s-sn"] !== "undefined") {
997
- if (getHostSlotNodes(this.__childNodes || this.childNodes, this.tagName, toRemove["s-sn"]) && toRemove.isConnected) {
998
- toRemove.remove();
998
+ const slotNode = getHostSlotNodes(this.__childNodes || this.childNodes, this.tagName, toRemove["s-sn"]);
999
+ if (slotNode && toRemove.isConnected) {
1000
+ removeSlottedNode(toRemove);
1001
+ if (slotNode[0]) dispatchSlotChangeEvent(slotNode[0]);
999
1002
  updateFallbackSlotVisibility(this);
1000
1003
  return;
1001
1004
  }
@@ -1018,6 +1021,7 @@ const patchSlotPrepend = (HostElementPrototype) => {
1018
1021
  const slotNode = getHostSlotNodes(internalCall(this, "childNodes"), this.tagName, slotName)[0];
1019
1022
  if (slotNode) {
1020
1023
  addSlotRelocateNode(newChild, slotNode, true);
1024
+ patchSlottedNode(newChild);
1021
1025
  const appendAfter = getSlotChildSiblings(slotNode, slotName)[0];
1022
1026
  const toReturn = internalCall(internalCall(appendAfter, "parentNode"), "insertBefore")(newChild, internalCall(appendAfter, "nextSibling"));
1023
1027
  dispatchSlotChangeEvent(slotNode);
@@ -1093,6 +1097,7 @@ const patchInsertBefore = (HostElementPrototype) => {
1093
1097
  }
1094
1098
  if (slotName === currentChild["s-sn"]) {
1095
1099
  addSlotRelocateNode(newChild, slotNode);
1100
+ patchSlottedNode(newChild);
1096
1101
  internalCall(internalCall(currentChild, "parentNode"), "insertBefore")(newChild, currentChild);
1097
1102
  dispatchSlotChangeEvent(slotNode);
1098
1103
  }
@@ -1171,10 +1176,21 @@ const patchChildSlotNodes = (elm) => {
1171
1176
  } });
1172
1177
  };
1173
1178
  /**
1174
- * Patches sibling accessors of a 'slotted' node within a non-shadow component.
1175
- * Meaning whilst stepping through a non-shadow element's nodes, only the mock 'lightDOM' nodes are returned.
1176
- * Especially relevant when rendering components via SSR... Frameworks will often try to reconcile their
1177
- * VDOM with the real DOM by stepping through nodes with 'nextSibling' et al.
1179
+ * Patches a node slotted into a non-shadow component so it behaves as it would in a native slot:
1180
+ * - `parentNode` returns the host element
1181
+ * - `remove()` fires `slotchange` on the node's slot
1182
+ *
1183
+ * @param node the slotted node to be patched
1184
+ */
1185
+ const patchSlottedNode = (node) => {
1186
+ patchParentNode(node);
1187
+ patchSlottedRemove(node);
1188
+ };
1189
+ /**
1190
+ * Patches a slotted node from SSR markup: everything {@link patchSlottedNode} does, plus its
1191
+ * sibling accessors, so whilst stepping through a non-shadow element's nodes only the mock
1192
+ * 'lightDOM' nodes are returned. Frameworks hydrating SSR output often reconcile their VDOM with
1193
+ * the real DOM by stepping through nodes with 'nextSibling' et al.
1178
1194
  * - `nextSibling`
1179
1195
  * - `nextElementSibling`
1180
1196
  * - `previousSibling`
@@ -1182,11 +1198,11 @@ const patchChildSlotNodes = (elm) => {
1182
1198
  *
1183
1199
  * @param node the slotted node to be patched
1184
1200
  */
1185
- const patchSlottedNode = (node) => {
1201
+ const patchSsrSlottedNode = (node) => {
1186
1202
  if (!node || node.__nextSibling !== void 0 || !globalThis.Node) return;
1187
1203
  patchNextSibling(node);
1188
1204
  patchPreviousSibling(node);
1189
- patchParentNode(node);
1205
+ patchSlottedNode(node);
1190
1206
  if (node.nodeType === Node.ELEMENT_NODE) {
1191
1207
  patchNextElementSibling(node);
1192
1208
  patchPreviousElementSibling(node);
@@ -1253,6 +1269,39 @@ const patchPreviousElementSibling = (element) => {
1253
1269
  } });
1254
1270
  };
1255
1271
  /**
1272
+ * Detaches a slotted node from where it physically sits in the component's rendered DOM, through
1273
+ * the unpatched accessors. Not via `remove()`: mock-doc's `remove()` calls
1274
+ * `parentNode.removeChild()`, and a slotted node's patched `parentNode` is the host, whose patched
1275
+ * `removeChild()` would come straight back here.
1276
+ *
1277
+ * @param node the slotted node to detach
1278
+ */
1279
+ const removeSlottedNode = (node) => {
1280
+ const parent = internalCall(node, "parentNode");
1281
+ if (parent) internalCall(parent, "removeChild")(node);
1282
+ };
1283
+ /**
1284
+ * Patches `remove()` on a node slotted into a non-shadow component, so that removing it fires
1285
+ * `slotchange` on its slot (and updates fallback content), as removing a node from a native slot
1286
+ * does. Stencil's own node moves, while `isTmpDisconnected` is set, don't fire it.
1287
+ *
1288
+ * @param node the slotted node to patch
1289
+ */
1290
+ const patchSlottedRemove = (node) => {
1291
+ const child = node;
1292
+ if (!child || child.__remove || typeof child.remove !== "function") return;
1293
+ child.__remove = child.remove;
1294
+ child.remove = function() {
1295
+ const host = this["s-ol"]?.parentElement;
1296
+ const { slotNode } = findSlotFromSlottedNode(this);
1297
+ removeSlottedNode(this);
1298
+ if (slotNode && !(plt.$flags$ & PLATFORM_FLAGS.isTmpDisconnected)) {
1299
+ dispatchSlotChangeEvent(slotNode);
1300
+ updateFallbackSlotVisibility(host);
1301
+ }
1302
+ };
1303
+ };
1304
+ /**
1256
1305
  * Patches the `parentNode` accessor of a non-shadow slotted node
1257
1306
  *
1258
1307
  * @param node the slotted node to be patched
@@ -1991,6 +2040,7 @@ let isSvgMode = false;
1991
2040
  * These ensure that ref callbacks are called in the correct order:
1992
2041
  * first all removal callbacks (with null), then all attachment callbacks (with elements).
1993
2042
  */
2043
+ const initialSlotChanges = /* @__PURE__ */ new Set();
1994
2044
  const refCallbacksToRemove = [];
1995
2045
  const refCallbacksToAttach = [];
1996
2046
  /** Disposers for signal subscriptions on individual DOM nodes (text nodes, <s-show> wrappers). */
@@ -2545,10 +2595,13 @@ const insertBefore = (parent, newNode, reference, isInitialLoad) => {
2545
2595
  if (BUILD$1.scoped && typeof newNode["s-sn"] === "string" && !!newNode["s-sr"] && !!newNode["s-cr"]) addRemoveSlotScopedClass(newNode["s-cr"], newNode, parent, newNode.parentElement);
2546
2596
  else if (typeof newNode["s-sn"] === "string") {
2547
2597
  const hostElm = newNode["s-hn"] && parent.closest?.(newNode["s-hn"]);
2548
- if ((BUILD$1.lightDomPatches || BUILD$1.slotChildNodes || BUILD$1.patchAll && !!(hostElm && getHostRef(hostElm)?.$cmpMeta$.$flags$ & CMP_FLAGS.patchAll)) && parent.getRootNode().nodeType !== NODE_TYPES.DOCUMENT_FRAGMENT_NODE) patchParentNode(newNode);
2598
+ if ((BUILD$1.lightDomPatches || BUILD$1.slotChildNodes || BUILD$1.patchAll && !!(hostElm && getHostRef(hostElm)?.$cmpMeta$.$flags$ & CMP_FLAGS.patchAll)) && parent.getRootNode().nodeType !== NODE_TYPES.DOCUMENT_FRAGMENT_NODE) patchSlottedNode(newNode);
2549
2599
  parent.insertBefore(newNode, reference);
2550
2600
  const { slotNode } = findSlotFromSlottedNode(newNode);
2551
- if (slotNode && !isInitialLoad) dispatchSlotChangeEvent(slotNode);
2601
+ if (slotNode) {
2602
+ if (isInitialLoad) initialSlotChanges.add(slotNode);
2603
+ else dispatchSlotChangeEvent(slotNode);
2604
+ }
2552
2605
  return newNode;
2553
2606
  }
2554
2607
  }
@@ -2704,6 +2757,11 @@ render() {
2704
2757
  if (checkSlotFallbackVisibility) updateFallbackSlotVisibility(rootVnode.$elm$);
2705
2758
  plt.$flags$ &= ~PLATFORM_FLAGS.isTmpDisconnected;
2706
2759
  relocateNodes.length = 0;
2760
+ if (initialSlotChanges.size) {
2761
+ const slotNodes = [...initialSlotChanges];
2762
+ initialSlotChanges.clear();
2763
+ nextTick(() => slotNodes.forEach(dispatchSlotChangeEvent));
2764
+ }
2707
2765
  }
2708
2766
  if (BUILD$1.slotRelocation && !useNativeShadowDom && !(cmpMeta.$flags$ & CMP_FLAGS.shadowDomEncapsulation) && hostElm["s-cr"]) {
2709
2767
  const children = rootVnode.$elm$.__childNodes || rootVnode.$elm$.childNodes;
@@ -3456,7 +3514,7 @@ const initializeClientHydrate = (hostElm, tagName, hostId, hostRef) => {
3456
3514
  }
3457
3515
  addSlotRelocateNode(siNode, siSlot, false, siNode["s-oo"] || currentPos);
3458
3516
  if (siNode.parentElement?.shadowRoot && siNode["getAttribute"] && siNode.getAttribute("slot")) siNode.removeAttribute("slot");
3459
- if (BUILD$1.lightDomPatches || BUILD$1.slotChildNodes || BUILD$1.patchAll && hostRef.$cmpMeta$.$flags$ & CMP_FLAGS.patchAll) patchSlottedNode(siNode);
3517
+ if (BUILD$1.lightDomPatches || BUILD$1.slotChildNodes || BUILD$1.patchAll && hostRef.$cmpMeta$.$flags$ & CMP_FLAGS.patchAll) patchSsrSlottedNode(siNode);
3460
3518
  }
3461
3519
  currentPos = (siNode["s-oo"] || currentPos) + 1;
3462
3520
  }
@@ -1,4 +1,4 @@
1
- import { C as ReactiveControllerHostInterface, E as VNode, S as MixedInCtor, T as TagTransformer, _ as ComponentInterface, a as ComponentConstructor, b as HTMLStencilElement, c as ComponentRuntimeMeta, d as HostRef, f as LazyBundlesRuntimeData, g as RuntimeRef, h as RenderNode, i as ChildType, l as ComponentRuntimeMetaCompact, m as PropsType, o as ComponentConstructorChangeHandlers, p as PlatformRuntime, s as ComponentRuntimeHostListener, u as HostElement, v as CustomElementsDefineOptions, w as ResolutionHandler, x as JSXBase, y as FunctionalComponent } from "../index-BHciXst1.js";
1
+ import { C as ReactiveControllerHostInterface, E as VNode, S as MixedInCtor, T as TagTransformer, _ as ComponentInterface, a as ComponentConstructor, b as HTMLStencilElement, c as ComponentRuntimeMeta, d as HostRef, f as LazyBundlesRuntimeData, g as RuntimeRef, h as RenderNode, i as ChildType, l as ComponentRuntimeMetaCompact, m as PropsType, o as ComponentConstructorChangeHandlers, p as PlatformRuntime, s as ComponentRuntimeHostListener, u as HostElement, v as CustomElementsDefineOptions, w as ResolutionHandler, x as JSXBase, y as FunctionalComponent } from "../index-CicD4Pgn.js";
2
2
  //#region src/runtime/asset-path.d.ts
3
3
  declare const getAssetPath: (path: string) => string;
4
4
  declare const setAssetPath: (path: string) => string;
@@ -844,6 +844,7 @@ const patchSlotAppendChild = (HostElementPrototype) => {
844
844
  const { slotName, slotNode } = findSlotFromSlottedNode(newChild, this);
845
845
  if (slotNode) {
846
846
  addSlotRelocateNode(newChild, slotNode);
847
+ patchSlottedNode(newChild);
847
848
  const slotChildNodes = getSlotChildSiblings(slotNode, slotName);
848
849
  const appendAfter = slotChildNodes[slotChildNodes.length - 1];
849
850
  const insertedNode = internalCall(internalCall(appendAfter, "parentNode"), "insertBefore")(newChild, appendAfter.nextSibling);
@@ -866,8 +867,10 @@ const patchSlotRemoveChild = (ElementPrototype) => {
866
867
  ElementPrototype.__removeChild = ElementPrototype.removeChild;
867
868
  ElementPrototype.removeChild = function(toRemove) {
868
869
  if (toRemove && typeof toRemove["s-sn"] !== "undefined") {
869
- if (getHostSlotNodes(this.__childNodes || this.childNodes, this.tagName, toRemove["s-sn"]) && toRemove.isConnected) {
870
- toRemove.remove();
870
+ const slotNode = getHostSlotNodes(this.__childNodes || this.childNodes, this.tagName, toRemove["s-sn"]);
871
+ if (slotNode && toRemove.isConnected) {
872
+ removeSlottedNode(toRemove);
873
+ if (slotNode[0]) dispatchSlotChangeEvent(slotNode[0]);
871
874
  updateFallbackSlotVisibility(this);
872
875
  return;
873
876
  }
@@ -890,6 +893,7 @@ const patchSlotPrepend = (HostElementPrototype) => {
890
893
  const slotNode = getHostSlotNodes(internalCall(this, "childNodes"), this.tagName, slotName)[0];
891
894
  if (slotNode) {
892
895
  addSlotRelocateNode(newChild, slotNode, true);
896
+ patchSlottedNode(newChild);
893
897
  const appendAfter = getSlotChildSiblings(slotNode, slotName)[0];
894
898
  const toReturn = internalCall(internalCall(appendAfter, "parentNode"), "insertBefore")(newChild, internalCall(appendAfter, "nextSibling"));
895
899
  dispatchSlotChangeEvent(slotNode);
@@ -965,6 +969,7 @@ const patchInsertBefore = (HostElementPrototype) => {
965
969
  }
966
970
  if (slotName === currentChild["s-sn"]) {
967
971
  addSlotRelocateNode(newChild, slotNode);
972
+ patchSlottedNode(newChild);
968
973
  internalCall(internalCall(currentChild, "parentNode"), "insertBefore")(newChild, currentChild);
969
974
  dispatchSlotChangeEvent(slotNode);
970
975
  }
@@ -1043,10 +1048,21 @@ const patchChildSlotNodes = (elm) => {
1043
1048
  } });
1044
1049
  };
1045
1050
  /**
1046
- * Patches sibling accessors of a 'slotted' node within a non-shadow component.
1047
- * Meaning whilst stepping through a non-shadow element's nodes, only the mock 'lightDOM' nodes are returned.
1048
- * Especially relevant when rendering components via SSR... Frameworks will often try to reconcile their
1049
- * VDOM with the real DOM by stepping through nodes with 'nextSibling' et al.
1051
+ * Patches a node slotted into a non-shadow component so it behaves as it would in a native slot:
1052
+ * - `parentNode` returns the host element
1053
+ * - `remove()` fires `slotchange` on the node's slot
1054
+ *
1055
+ * @param node the slotted node to be patched
1056
+ */
1057
+ const patchSlottedNode = (node) => {
1058
+ patchParentNode(node);
1059
+ patchSlottedRemove(node);
1060
+ };
1061
+ /**
1062
+ * Patches a slotted node from SSR markup: everything {@link patchSlottedNode} does, plus its
1063
+ * sibling accessors, so whilst stepping through a non-shadow element's nodes only the mock
1064
+ * 'lightDOM' nodes are returned. Frameworks hydrating SSR output often reconcile their VDOM with
1065
+ * the real DOM by stepping through nodes with 'nextSibling' et al.
1050
1066
  * - `nextSibling`
1051
1067
  * - `nextElementSibling`
1052
1068
  * - `previousSibling`
@@ -1054,11 +1070,11 @@ const patchChildSlotNodes = (elm) => {
1054
1070
  *
1055
1071
  * @param node the slotted node to be patched
1056
1072
  */
1057
- const patchSlottedNode = (node) => {
1073
+ const patchSsrSlottedNode = (node) => {
1058
1074
  if (!node || node.__nextSibling !== void 0 || !globalThis.Node) return;
1059
1075
  patchNextSibling(node);
1060
1076
  patchPreviousSibling(node);
1061
- patchParentNode(node);
1077
+ patchSlottedNode(node);
1062
1078
  if (node.nodeType === Node.ELEMENT_NODE) {
1063
1079
  patchNextElementSibling(node);
1064
1080
  patchPreviousElementSibling(node);
@@ -1125,6 +1141,39 @@ const patchPreviousElementSibling = (element) => {
1125
1141
  } });
1126
1142
  };
1127
1143
  /**
1144
+ * Detaches a slotted node from where it physically sits in the component's rendered DOM, through
1145
+ * the unpatched accessors. Not via `remove()`: mock-doc's `remove()` calls
1146
+ * `parentNode.removeChild()`, and a slotted node's patched `parentNode` is the host, whose patched
1147
+ * `removeChild()` would come straight back here.
1148
+ *
1149
+ * @param node the slotted node to detach
1150
+ */
1151
+ const removeSlottedNode = (node) => {
1152
+ const parent = internalCall(node, "parentNode");
1153
+ if (parent) internalCall(parent, "removeChild")(node);
1154
+ };
1155
+ /**
1156
+ * Patches `remove()` on a node slotted into a non-shadow component, so that removing it fires
1157
+ * `slotchange` on its slot (and updates fallback content), as removing a node from a native slot
1158
+ * does. Stencil's own node moves, while `isTmpDisconnected` is set, don't fire it.
1159
+ *
1160
+ * @param node the slotted node to patch
1161
+ */
1162
+ const patchSlottedRemove = (node) => {
1163
+ const child = node;
1164
+ if (!child || child.__remove || typeof child.remove !== "function") return;
1165
+ child.__remove = child.remove;
1166
+ child.remove = function() {
1167
+ const host = this["s-ol"]?.parentElement;
1168
+ const { slotNode } = findSlotFromSlottedNode(this);
1169
+ removeSlottedNode(this);
1170
+ if (slotNode && !(plt.$flags$ & PLATFORM_FLAGS.isTmpDisconnected)) {
1171
+ dispatchSlotChangeEvent(slotNode);
1172
+ updateFallbackSlotVisibility(host);
1173
+ }
1174
+ };
1175
+ };
1176
+ /**
1128
1177
  * Patches the `parentNode` accessor of a non-shadow slotted node
1129
1178
  *
1130
1179
  * @param node the slotted node to be patched
@@ -1863,6 +1912,7 @@ let isSvgMode = false;
1863
1912
  * These ensure that ref callbacks are called in the correct order:
1864
1913
  * first all removal callbacks (with null), then all attachment callbacks (with elements).
1865
1914
  */
1915
+ const initialSlotChanges = /* @__PURE__ */ new Set();
1866
1916
  const refCallbacksToRemove = [];
1867
1917
  const refCallbacksToAttach = [];
1868
1918
  /** Disposers for signal subscriptions on individual DOM nodes (text nodes, <s-show> wrappers). */
@@ -2417,10 +2467,13 @@ const insertBefore = (parent, newNode, reference, isInitialLoad) => {
2417
2467
  if (BUILD.scoped && typeof newNode["s-sn"] === "string" && !!newNode["s-sr"] && !!newNode["s-cr"]) addRemoveSlotScopedClass(newNode["s-cr"], newNode, parent, newNode.parentElement);
2418
2468
  else if (typeof newNode["s-sn"] === "string") {
2419
2469
  const hostElm = newNode["s-hn"] && parent.closest?.(newNode["s-hn"]);
2420
- 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);
2470
+ 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);
2421
2471
  parent.insertBefore(newNode, reference);
2422
2472
  const { slotNode } = findSlotFromSlottedNode(newNode);
2423
- if (slotNode && !isInitialLoad) dispatchSlotChangeEvent(slotNode);
2473
+ if (slotNode) {
2474
+ if (isInitialLoad) initialSlotChanges.add(slotNode);
2475
+ else dispatchSlotChangeEvent(slotNode);
2476
+ }
2424
2477
  return newNode;
2425
2478
  }
2426
2479
  }
@@ -2576,6 +2629,11 @@ render() {
2576
2629
  if (checkSlotFallbackVisibility) updateFallbackSlotVisibility(rootVnode.$elm$);
2577
2630
  plt.$flags$ &= ~PLATFORM_FLAGS.isTmpDisconnected;
2578
2631
  relocateNodes.length = 0;
2632
+ if (initialSlotChanges.size) {
2633
+ const slotNodes = [...initialSlotChanges];
2634
+ initialSlotChanges.clear();
2635
+ nextTick(() => slotNodes.forEach(dispatchSlotChangeEvent));
2636
+ }
2579
2637
  }
2580
2638
  if (BUILD.slotRelocation && !useNativeShadowDom && !(cmpMeta.$flags$ & CMP_FLAGS.shadowDomEncapsulation) && hostElm["s-cr"]) {
2581
2639
  const children = rootVnode.$elm$.__childNodes || rootVnode.$elm$.childNodes;
@@ -3328,7 +3386,7 @@ const initializeClientHydrate = (hostElm, tagName, hostId, hostRef) => {
3328
3386
  }
3329
3387
  addSlotRelocateNode(siNode, siSlot, false, siNode["s-oo"] || currentPos);
3330
3388
  if (siNode.parentElement?.shadowRoot && siNode["getAttribute"] && siNode.getAttribute("slot")) siNode.removeAttribute("slot");
3331
- if (BUILD.lightDomPatches || BUILD.slotChildNodes || BUILD.patchAll && hostRef.$cmpMeta$.$flags$ & CMP_FLAGS.patchAll) patchSlottedNode(siNode);
3389
+ if (BUILD.lightDomPatches || BUILD.slotChildNodes || BUILD.patchAll && hostRef.$cmpMeta$.$flags$ & CMP_FLAGS.patchAll) patchSsrSlottedNode(siNode);
3332
3390
  }
3333
3391
  currentPos = (siNode["s-oo"] || currentPos) + 1;
3334
3392
  }
@@ -640,6 +640,7 @@ const patchSlotAppendChild = (HostElementPrototype) => {
640
640
  const { slotName, slotNode } = findSlotFromSlottedNode(newChild, this);
641
641
  if (slotNode) {
642
642
  addSlotRelocateNode(newChild, slotNode);
643
+ patchSlottedNode(newChild);
643
644
  const slotChildNodes = getSlotChildSiblings(slotNode, slotName);
644
645
  const appendAfter = slotChildNodes[slotChildNodes.length - 1];
645
646
  const insertedNode = internalCall(internalCall(appendAfter, "parentNode"), "insertBefore")(newChild, appendAfter.nextSibling);
@@ -662,8 +663,10 @@ const patchSlotRemoveChild = (ElementPrototype) => {
662
663
  ElementPrototype.__removeChild = ElementPrototype.removeChild;
663
664
  ElementPrototype.removeChild = function(toRemove) {
664
665
  if (toRemove && typeof toRemove["s-sn"] !== "undefined") {
665
- if (getHostSlotNodes(this.__childNodes || this.childNodes, this.tagName, toRemove["s-sn"]) && toRemove.isConnected) {
666
- toRemove.remove();
666
+ const slotNode = getHostSlotNodes(this.__childNodes || this.childNodes, this.tagName, toRemove["s-sn"]);
667
+ if (slotNode && toRemove.isConnected) {
668
+ removeSlottedNode(toRemove);
669
+ if (slotNode[0]) dispatchSlotChangeEvent(slotNode[0]);
667
670
  updateFallbackSlotVisibility(this);
668
671
  return;
669
672
  }
@@ -686,6 +689,7 @@ const patchSlotPrepend = (HostElementPrototype) => {
686
689
  const slotNode = getHostSlotNodes(internalCall(this, "childNodes"), this.tagName, slotName)[0];
687
690
  if (slotNode) {
688
691
  addSlotRelocateNode(newChild, slotNode, true);
692
+ patchSlottedNode(newChild);
689
693
  const appendAfter = getSlotChildSiblings(slotNode, slotName)[0];
690
694
  const toReturn = internalCall(internalCall(appendAfter, "parentNode"), "insertBefore")(newChild, internalCall(appendAfter, "nextSibling"));
691
695
  dispatchSlotChangeEvent(slotNode);
@@ -761,6 +765,7 @@ const patchInsertBefore = (HostElementPrototype) => {
761
765
  }
762
766
  if (slotName === currentChild["s-sn"]) {
763
767
  addSlotRelocateNode(newChild, slotNode);
768
+ patchSlottedNode(newChild);
764
769
  internalCall(internalCall(currentChild, "parentNode"), "insertBefore")(newChild, currentChild);
765
770
  dispatchSlotChangeEvent(slotNode);
766
771
  }
@@ -839,10 +844,21 @@ const patchChildSlotNodes = (elm) => {
839
844
  } });
840
845
  };
841
846
  /**
842
- * Patches sibling accessors of a 'slotted' node within a non-shadow component.
843
- * Meaning whilst stepping through a non-shadow element's nodes, only the mock 'lightDOM' nodes are returned.
844
- * Especially relevant when rendering components via SSR... Frameworks will often try to reconcile their
845
- * VDOM with the real DOM by stepping through nodes with 'nextSibling' et al.
847
+ * Patches a node slotted into a non-shadow component so it behaves as it would in a native slot:
848
+ * - `parentNode` returns the host element
849
+ * - `remove()` fires `slotchange` on the node's slot
850
+ *
851
+ * @param node the slotted node to be patched
852
+ */
853
+ const patchSlottedNode = (node) => {
854
+ patchParentNode(node);
855
+ patchSlottedRemove(node);
856
+ };
857
+ /**
858
+ * Patches a slotted node from SSR markup: everything {@link patchSlottedNode} does, plus its
859
+ * sibling accessors, so whilst stepping through a non-shadow element's nodes only the mock
860
+ * 'lightDOM' nodes are returned. Frameworks hydrating SSR output often reconcile their VDOM with
861
+ * the real DOM by stepping through nodes with 'nextSibling' et al.
846
862
  * - `nextSibling`
847
863
  * - `nextElementSibling`
848
864
  * - `previousSibling`
@@ -850,11 +866,11 @@ const patchChildSlotNodes = (elm) => {
850
866
  *
851
867
  * @param node the slotted node to be patched
852
868
  */
853
- const patchSlottedNode = (node) => {
869
+ const patchSsrSlottedNode = (node) => {
854
870
  if (!node || node.__nextSibling !== void 0 || !globalThis.Node) return;
855
871
  patchNextSibling(node);
856
872
  patchPreviousSibling(node);
857
- patchParentNode(node);
873
+ patchSlottedNode(node);
858
874
  if (node.nodeType === Node.ELEMENT_NODE) {
859
875
  patchNextElementSibling(node);
860
876
  patchPreviousElementSibling(node);
@@ -921,6 +937,39 @@ const patchPreviousElementSibling = (element) => {
921
937
  } });
922
938
  };
923
939
  /**
940
+ * Detaches a slotted node from where it physically sits in the component's rendered DOM, through
941
+ * the unpatched accessors. Not via `remove()`: mock-doc's `remove()` calls
942
+ * `parentNode.removeChild()`, and a slotted node's patched `parentNode` is the host, whose patched
943
+ * `removeChild()` would come straight back here.
944
+ *
945
+ * @param node the slotted node to detach
946
+ */
947
+ const removeSlottedNode = (node) => {
948
+ const parent = internalCall(node, "parentNode");
949
+ if (parent) internalCall(parent, "removeChild")(node);
950
+ };
951
+ /**
952
+ * Patches `remove()` on a node slotted into a non-shadow component, so that removing it fires
953
+ * `slotchange` on its slot (and updates fallback content), as removing a node from a native slot
954
+ * does. Stencil's own node moves, while `isTmpDisconnected` is set, don't fire it.
955
+ *
956
+ * @param node the slotted node to patch
957
+ */
958
+ const patchSlottedRemove = (node) => {
959
+ const child = node;
960
+ if (!child || child.__remove || typeof child.remove !== "function") return;
961
+ child.__remove = child.remove;
962
+ child.remove = function() {
963
+ const host = this["s-ol"]?.parentElement;
964
+ const { slotNode } = findSlotFromSlottedNode(this);
965
+ removeSlottedNode(this);
966
+ if (slotNode && !(plt.$flags$ & PLATFORM_FLAGS.isTmpDisconnected)) {
967
+ dispatchSlotChangeEvent(slotNode);
968
+ updateFallbackSlotVisibility(host);
969
+ }
970
+ };
971
+ };
972
+ /**
924
973
  * Patches the `parentNode` accessor of a non-shadow slotted node
925
974
  *
926
975
  * @param node the slotted node to be patched
@@ -1627,6 +1676,7 @@ let isSvgMode = false;
1627
1676
  * These ensure that ref callbacks are called in the correct order:
1628
1677
  * first all removal callbacks (with null), then all attachment callbacks (with elements).
1629
1678
  */
1679
+ const initialSlotChanges = /* @__PURE__ */ new Set();
1630
1680
  const refCallbacksToRemove = [];
1631
1681
  const refCallbacksToAttach = [];
1632
1682
  /** Disposers for signal subscriptions on individual DOM nodes (text nodes, <s-show> wrappers). */
@@ -2181,10 +2231,13 @@ const insertBefore = (parent, newNode, reference, isInitialLoad) => {
2181
2231
  if (BUILD$1.scoped && typeof newNode["s-sn"] === "string" && !!newNode["s-sr"] && !!newNode["s-cr"]) addRemoveSlotScopedClass(newNode["s-cr"], newNode, parent, newNode.parentElement);
2182
2232
  else if (typeof newNode["s-sn"] === "string") {
2183
2233
  const hostElm = newNode["s-hn"] && parent.closest?.(newNode["s-hn"]);
2184
- if ((BUILD$1.lightDomPatches || BUILD$1.slotChildNodes || BUILD$1.patchAll && !!(hostElm && getHostRef(hostElm)?.$cmpMeta$.$flags$ & CMP_FLAGS.patchAll)) && parent.getRootNode().nodeType !== NODE_TYPES.DOCUMENT_FRAGMENT_NODE) patchParentNode(newNode);
2234
+ if ((BUILD$1.lightDomPatches || BUILD$1.slotChildNodes || BUILD$1.patchAll && !!(hostElm && getHostRef(hostElm)?.$cmpMeta$.$flags$ & CMP_FLAGS.patchAll)) && parent.getRootNode().nodeType !== NODE_TYPES.DOCUMENT_FRAGMENT_NODE) patchSlottedNode(newNode);
2185
2235
  parent.insertBefore(newNode, reference);
2186
2236
  const { slotNode } = findSlotFromSlottedNode(newNode);
2187
- if (slotNode && !isInitialLoad) dispatchSlotChangeEvent(slotNode);
2237
+ if (slotNode) {
2238
+ if (isInitialLoad) initialSlotChanges.add(slotNode);
2239
+ else dispatchSlotChangeEvent(slotNode);
2240
+ }
2188
2241
  return newNode;
2189
2242
  }
2190
2243
  }
@@ -2340,6 +2393,11 @@ render() {
2340
2393
  if (checkSlotFallbackVisibility) updateFallbackSlotVisibility(rootVnode.$elm$);
2341
2394
  plt.$flags$ &= ~PLATFORM_FLAGS.isTmpDisconnected;
2342
2395
  relocateNodes.length = 0;
2396
+ if (initialSlotChanges.size) {
2397
+ const slotNodes = [...initialSlotChanges];
2398
+ initialSlotChanges.clear();
2399
+ nextTick(() => slotNodes.forEach(dispatchSlotChangeEvent));
2400
+ }
2343
2401
  }
2344
2402
  if (BUILD$1.slotRelocation && !useNativeShadowDom && !(cmpMeta.$flags$ & CMP_FLAGS.shadowDomEncapsulation) && hostElm["s-cr"]) {
2345
2403
  const children = rootVnode.$elm$.__childNodes || rootVnode.$elm$.childNodes;
@@ -3090,7 +3148,7 @@ const initializeClientHydrate = (hostElm, tagName, hostId, hostRef) => {
3090
3148
  }
3091
3149
  addSlotRelocateNode(siNode, siSlot, false, siNode["s-oo"] || currentPos);
3092
3150
  if (siNode.parentElement?.shadowRoot && siNode["getAttribute"] && siNode.getAttribute("slot")) siNode.removeAttribute("slot");
3093
- if (BUILD$1.lightDomPatches || BUILD$1.slotChildNodes || BUILD$1.patchAll && hostRef.$cmpMeta$.$flags$ & CMP_FLAGS.patchAll) patchSlottedNode(siNode);
3151
+ if (BUILD$1.lightDomPatches || BUILD$1.slotChildNodes || BUILD$1.patchAll && hostRef.$cmpMeta$.$flags$ & CMP_FLAGS.patchAll) patchSsrSlottedNode(siNode);
3094
3152
  }
3095
3153
  currentPos = (siNode["s-oo"] || currentPos) + 1;
3096
3154
  }
@@ -1,4 +1,4 @@
1
- import { Bt as Logger, nt as CompilerSystem } from "../../index-BogZpjP2.mjs";
1
+ import { Bt as Logger, nt as CompilerSystem } from "../../index-m_QF4nMv.mjs";
2
2
  //#region src/sys/node/logger/index.d.ts
3
3
  /**
4
4
  * Create a logger to run in a Node environment
@@ -1,2 +1,2 @@
1
- import { n as setupNodeProcess, r as createNodeLogger, t as createNodeSys } from "../../node-CvPPhnWO.mjs";
1
+ import { n as setupNodeProcess, r as createNodeLogger, t as createNodeSys } from "../../node-D-21Ykxi.mjs";
2
2
  export { createNodeLogger, createNodeSys, setupNodeProcess };
@@ -1,5 +1,5 @@
1
- import { l as createWorkerMessageHandler } from "../../compiler-6RhuOkQ0.mjs";
2
- import { t as createNodeSys } from "../../node-CvPPhnWO.mjs";
1
+ import { l as createWorkerMessageHandler } from "../../compiler-BZEeAANv.mjs";
2
+ import { t as createNodeSys } from "../../node-D-21Ykxi.mjs";
3
3
  //#region src/sys/node/node-worker-thread.ts
4
4
  /**
5
5
  * Initialize a worker thread, setting up various machinery for managing
@@ -1526,7 +1526,8 @@ interface DevServerConfig extends StencilDevServerConfig {
1526
1526
  * reloading updates.
1527
1527
  */
1528
1528
  excludeHmr?: string[];
1529
- historyApiFallback?: HistoryApiFallback;
1529
+ /** Serve `index` for page requests that match no file (single-page app routes). `null` turns it off. */
1530
+ historyApiFallback?: HistoryApiFallback | null;
1530
1531
  openBrowser?: boolean;
1531
1532
  prerenderConfig?: string;
1532
1533
  protocol?: 'http' | 'https';