@stencil/core 5.0.0-alpha.9 → 5.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/README.md +94 -0
  2. package/dist/app-data/index.d.ts +1 -1
  3. package/dist/app-data/index.js +4 -1
  4. package/dist/client-BRu0GtRn.mjs +2368 -0
  5. package/dist/compiler/index.d.mts +167 -3
  6. package/dist/compiler/index.mjs +3 -3
  7. package/dist/compiler/utils/index.d.mts +272 -2
  8. package/dist/compiler/utils/index.mjs +4 -3
  9. package/dist/{compiler-C0qmPoKu.mjs → compiler-NrvbUOX1.mjs} +2754 -1259
  10. package/dist/declarations/stencil-ext-modules.d.ts +5 -5
  11. package/dist/declarations/stencil-public-compiler.d.ts +208 -66
  12. package/dist/declarations/stencil-public-docs.d.ts +9 -0
  13. package/dist/declarations/stencil-public-runtime.d.ts +91 -6
  14. package/dist/fragment-Di1hWOC8.mjs +4 -0
  15. package/dist/{regular-expression-CFVJOTUh.mjs → helpers-Cpp3qc3u.mjs} +31 -15
  16. package/dist/index-BOrz3rbJ.d.mts +100 -0
  17. package/dist/{index-xAkMgLX_.d.ts → index-DnISpqrd.d.ts} +149 -9
  18. package/dist/{index-vY35H18z.d.mts → index-RrQfiPWK.d.mts} +490 -845
  19. package/dist/index.d.mts +4 -0
  20. package/dist/index.mjs +91 -2
  21. package/dist/jsx-runtime.mjs +2 -1
  22. package/dist/{node--akYC-sG.mjs → node-75gQKkFz.mjs} +60 -58
  23. package/dist/{chunk-z9aeyW2b.mjs → rolldown-runtime-BhDjJH2R.mjs} +1 -1
  24. package/dist/runtime/client/lazy.js +481 -184
  25. package/dist/runtime/client/runtime.d.ts +149 -10
  26. package/dist/runtime/client/runtime.js +481 -184
  27. package/dist/runtime/index.d.ts +6 -4
  28. package/dist/runtime/index.js +480 -182
  29. package/dist/runtime/server/index.d.mts +80 -8
  30. package/dist/runtime/server/index.mjs +403 -177
  31. package/dist/runtime/server/runner.d.mts +3 -0
  32. package/dist/runtime/server/runner.mjs +320 -337
  33. package/dist/signals/index.d.ts +2 -0
  34. package/dist/signals/index.js +4 -1
  35. package/dist/sys/node/index.d.mts +1 -2
  36. package/dist/sys/node/index.mjs +1 -1
  37. package/dist/sys/node/worker.d.mts +1 -1
  38. package/dist/sys/node/worker.mjs +6 -3
  39. package/dist/testing/index.d.mts +4716 -105
  40. package/dist/testing/index.mjs +7590 -794
  41. package/dist/util-IKfWWLJo.mjs +724 -0
  42. package/dist/validation-DAdGTrys.mjs +791 -0
  43. package/package.json +27 -27
  44. package/dist/client-aTQ7xHxx.mjs +0 -4678
  45. package/dist/index-BvkyxSY6.d.mts +0 -205
  46. package/dist/validation-ByxKj8bC.mjs +0 -1458
  47. /package/{LICENSE.md → LICENSE} +0 -0
@@ -50,8 +50,20 @@ const HOST_FLAGS = {
50
50
  isWatchReady: 128,
51
51
  isListenReady: 256,
52
52
  needsRerender: 512,
53
- devOnRender: 1024,
54
- devOnDidLoad: 2048
53
+ /**
54
+ * Set once this component's real (lazy-loaded) `connectedCallback` has fired for
55
+ * the first time. Lets a descendant skip creating/awaiting a connect-promise for
56
+ * an ancestor that's already connected. See {@link HostRef.$onFirstConnectResolve$}.
57
+ */
58
+ hasFiredConnected: 1024,
59
+ /**
60
+ * Set when a lazy component's dynamic `import()` fails to resolve a
61
+ * constructor. Distinct from `hasInitializedComponent` being unset, which
62
+ * is true while an initialization attempt is merely queued/in-flight.
63
+ */
64
+ hasFailedLoad: 2048,
65
+ devOnRender: 4096,
66
+ devOnDidLoad: 8192
55
67
  };
56
68
  const CF_scopedCssEncapsulation = 2;
57
69
  /**
@@ -136,7 +148,17 @@ const CMP_FLAGS = {
136
148
  * e.g. `encapsulation: { type: 'none', patches: ['all'] }`
137
149
  * Equivalent to the global `experimentalSlotFixes` config option.
138
150
  */
139
- patchAll: 32768
151
+ patchAll: 32768,
152
+ /**
153
+ * Determines if `clonable` is enabled for a component that uses the shadow DOM.
154
+ * e.g. `encapsulation: { type: 'shadow', clonable: true }` is set on the `@Component()` decorator
155
+ */
156
+ shadowClonable: 65536,
157
+ /**
158
+ * Determines if `serializable` is enabled for a component that uses the shadow DOM.
159
+ * e.g. `encapsulation: { type: 'shadow', serializable: true }` is set on the `@Component()` decorator
160
+ */
161
+ shadowSerializable: 1 << 17
140
162
  };
141
163
  /**
142
164
  * Namespaces
@@ -270,8 +292,13 @@ const registerHost = (hostElement, cmpMeta) => {
270
292
  if (BUILD.asyncLoading) {
271
293
  hostRef.$onReadyPromise$ = new Promise((r) => hostRef.$onReadyResolve$ = r);
272
294
  hostElement["s-rp"] = hostRef.$onReadyPromise$;
295
+ if (!BUILD.lazyLoad) {
296
+ hostRef.$onFirstConnectPromise$ = new Promise((r) => hostRef.$onFirstConnectResolve$ = r);
297
+ hostElement["s-fc"] = hostRef.$onFirstConnectPromise$;
298
+ }
273
299
  if (!hostElement["s-p"]) hostElement["s-p"] = [];
274
300
  if (!hostElement["s-rc"]) hostElement["s-rc"] = [];
301
+ if (!hostElement["s-pc"]) hostElement["s-pc"] = [];
275
302
  }
276
303
  if (BUILD.lazyLoad) hostRef.$fetchedCbList$ = [];
277
304
  const ref = hostRef;
@@ -286,7 +313,12 @@ const consoleDevError = (...m) => console.error(...STENCIL_DEV_MODE, ...m);
286
313
  const consoleDevWarn = (...m) => console.warn(...STENCIL_DEV_MODE, ...m);
287
314
  //#endregion
288
315
  //#region src/client/client-load-module.ts
289
- const cmpModules = /* @__PURE__ */ new Map();
316
+ const cmpModules = /*@__PURE__*/ new Map();
317
+ /**
318
+ * Tracks how many times a dynamic `import()` for a given lazy bundle has failed.
319
+ * Used to cache bust the retry attempt in connected-callback.ts
320
+ */
321
+ const failedLoadAttempts = /*@__PURE__*/ new Map();
290
322
  /**
291
323
  * We need to separate out this prefix so that Esbuild doesn't try to resolve
292
324
  * the below, but instead retains a dynamic `import()` statement in the
@@ -313,13 +345,21 @@ const loadModule = (cmpMeta, hostRef, hmrVersionId) => {
313
345
  } else if (!bundleId) return;
314
346
  const module = !BUILD.hotModuleReplacement ? cmpModules.get(bundleId) : false;
315
347
  if (module) return module[exportName];
348
+ const retryCount = failedLoadAttempts.get(bundleId) ?? 0;
349
+ const cacheBustParams = [retryCount > 0 ? `s-retry=${retryCount}` : "", BUILD.hotModuleReplacement && hmrVersionId ? `s-hmr=${hmrVersionId}` : ""].filter(Boolean).join("&");
316
350
  /*!__STENCIL_STATIC_IMPORT_SWITCH__*/
317
- const entryFile = `${bundleId}.entry.js${BUILD.hotModuleReplacement && hmrVersionId ? "?s-hmr=" + hmrVersionId : ""}`;
351
+ const entryFile = `${bundleId}.entry.js${cacheBustParams ? "?" + cacheBustParams : ""}`;
318
352
  const onLoad = (importedModule) => {
319
- if (!BUILD.hotModuleReplacement) cmpModules.set(bundleId, importedModule);
353
+ if (!BUILD.hotModuleReplacement) {
354
+ failedLoadAttempts.delete(bundleId);
355
+ cmpModules.set(bundleId, importedModule);
356
+ }
320
357
  return importedModule[exportName];
321
358
  };
322
- const onError = (e) => consoleError(e, hostRef.$hostElement$);
359
+ const onError = (e) => {
360
+ failedLoadAttempts.set(bundleId, retryCount + 1);
361
+ consoleError(e, hostRef.$hostElement$);
362
+ };
323
363
  return import(
324
364
  /* @vite-ignore */
325
365
  /* webpackInclude: /\.entry\.js$/ */
@@ -330,7 +370,7 @@ const loadModule = (cmpMeta, hostRef, hmrVersionId) => {
330
370
  };
331
371
  //#endregion
332
372
  //#region src/client/client-style.ts
333
- const styles = /* @__PURE__ */ new Map();
373
+ const styles = /*@__PURE__*/ new Map();
334
374
  const modeResolutionChain = [];
335
375
  const needsScopedSSR = () => false;
336
376
  //#endregion
@@ -392,6 +432,10 @@ const HYDRATED_CSS = "{visibility:hidden}.hydrated{visibility:inherit}";
392
432
  */
393
433
  const SLOT_FB_CSS = "slot-fb{display:contents}slot-fb[hidden]{display:none}";
394
434
  const XLINK_NS = "http://www.w3.org/1999/xlink";
435
+ /**
436
+ * Minimum delay, in milliseconds, before retrying a failed lazy component load.
437
+ */
438
+ const LAZY_LOAD_RETRY_INTERVAL_MS = 1e3;
395
439
  const FORM_ASSOCIATED_CUSTOM_ELEMENT_CALLBACKS = [
396
440
  "formAssociatedCallback",
397
441
  "formResetCallback",
@@ -411,7 +455,7 @@ const plt = {
411
455
  rel: (el, eventName, listener, opts) => el.removeEventListener(eventName, listener, opts),
412
456
  ce: (eventName, opts) => new CustomEvent(eventName, opts)
413
457
  };
414
- const supportsListenerOptions = /* @__PURE__ */ (() => {
458
+ const supportsListenerOptions = /*@__PURE__*/ (() => {
415
459
  let supported = false;
416
460
  try {
417
461
  win.document?.addEventListener("e", null, Object.defineProperty({}, "passive", { get() {
@@ -421,14 +465,14 @@ const supportsListenerOptions = /* @__PURE__ */ (() => {
421
465
  return supported;
422
466
  })();
423
467
  const promiseResolve = (v) => Promise.resolve(v);
424
- const supportsConstructableStylesheets = BUILD.constructableCSS ? /* @__PURE__ */ (() => {
468
+ const supportsConstructableStylesheets = BUILD.constructableCSS ? /*@__PURE__*/ (() => {
425
469
  try {
426
470
  if (!win.document.adoptedStyleSheets) return false;
427
471
  return typeof new CSSStyleSheet().replaceSync === "function";
428
472
  } catch {}
429
473
  return false;
430
474
  })() : false;
431
- const supportsMutableAdoptedStyleSheets = supportsConstructableStylesheets ? /* @__PURE__ */ (() => !!win.document && Object.getOwnPropertyDescriptor(win.document.adoptedStyleSheets, "length").writable)() : false;
475
+ const supportsMutableAdoptedStyleSheets = supportsConstructableStylesheets ? /*@__PURE__*/ (() => !!win.document && Object.getOwnPropertyDescriptor(win.document.adoptedStyleSheets, "length").writable)() : false;
432
476
  //#endregion
433
477
  //#region src/client/client-task-queue.ts
434
478
  let queueCongestion = 0;
@@ -436,12 +480,13 @@ let queuePending = false;
436
480
  const queueDomReads = [];
437
481
  const queueDomWrites = [];
438
482
  const queueDomWritesLow = [];
483
+ const scheduleFlush = () => win.document?.hidden ? nextTick(flush) : plt.raf(flush);
439
484
  const queueTask = (queue, write) => (cb) => {
440
485
  queue.push(cb);
441
486
  if (!queuePending) {
442
487
  queuePending = true;
443
488
  if (write && plt.$flags$ & PLATFORM_FLAGS.queueSync) nextTick(flush);
444
- else plt.raf(flush);
489
+ else scheduleFlush();
445
490
  }
446
491
  };
447
492
  const consume = (queue) => {
@@ -474,15 +519,15 @@ const flush = () => {
474
519
  queueDomWritesLow.push(...queueDomWrites);
475
520
  queueDomWrites.length = 0;
476
521
  }
477
- if (queuePending = queueDomReads.length + queueDomWrites.length + queueDomWritesLow.length > 0) plt.raf(flush);
522
+ if (queuePending = queueDomReads.length + queueDomWrites.length + queueDomWritesLow.length > 0) scheduleFlush();
478
523
  else queueCongestion = 0;
479
524
  } else {
480
525
  consume(queueDomWrites);
481
- if (queuePending = queueDomReads.length > 0) plt.raf(flush);
526
+ if (queuePending = queueDomReads.length > 0) scheduleFlush();
482
527
  }
483
528
  };
484
529
  const nextTick = (cb) => promiseResolve().then(cb);
485
- const writeTask = /* @__PURE__ */ queueTask(queueDomWrites, true);
530
+ const writeTask = /*@__PURE__*/ queueTask(queueDomWrites, true);
486
531
  //#endregion
487
532
  //#region src/runtime/asset-path.ts
488
533
  const getAssetPath = (path) => {
@@ -518,11 +563,15 @@ function createShadowRoot(cmpMeta) {
518
563
  if (BUILD.shadowSlotAssignmentManual) {
519
564
  if (!!(cmpMeta.$flags$ & CMP_FLAGS.shadowSlotAssignmentManual)) opts.slotAssignment = "manual";
520
565
  }
566
+ if (BUILD.shadowClonable) opts.clonable = !!(cmpMeta.$flags$ & CMP_FLAGS.shadowClonable);
567
+ if (BUILD.shadowSerializable) opts.serializable = !!(cmpMeta.$flags$ & CMP_FLAGS.shadowSerializable);
521
568
  const shadowRoot = this.attachShadow(opts);
522
569
  if (BUILD.shadowModeClosed && isClosed) this.__shadowRoot = shadowRoot;
523
570
  if (globalStyleSheet === void 0) globalStyleSheet = createStyleSheetIfNeededAndSupported("") ?? null;
524
- if (globalStyleSheet) if (supportsMutableAdoptedStyleSheets) shadowRoot.adoptedStyleSheets.push(globalStyleSheet);
525
- else shadowRoot.adoptedStyleSheets = [...shadowRoot.adoptedStyleSheets, globalStyleSheet];
571
+ if (globalStyleSheet) {
572
+ if (supportsMutableAdoptedStyleSheets) shadowRoot.adoptedStyleSheets.push(globalStyleSheet);
573
+ else shadowRoot.adoptedStyleSheets = [...shadowRoot.adoptedStyleSheets, globalStyleSheet];
574
+ }
526
575
  }
527
576
  //#endregion
528
577
  //#region src/runtime/slot-polyfill-utils.ts
@@ -542,8 +591,10 @@ function createShadowRoot(cmpMeta) {
542
591
  const updateFallbackSlotVisibility = (elm) => {
543
592
  const childNodes = internalCall(elm, "childNodes");
544
593
  if (elm.tagName && elm.tagName.includes("-") && elm["s-cr"] && elm.tagName !== "SLOT-FB") getHostSlotNodes(childNodes, elm.tagName).forEach((slotNode) => {
545
- if (slotNode.nodeType === NODE_TYPE.ElementNode && slotNode.tagName === "SLOT-FB") if (getSlotChildSiblings(slotNode, getSlotName(slotNode), false).length) slotNode.hidden = true;
546
- else slotNode.hidden = false;
594
+ if (slotNode.nodeType === NODE_TYPE.ElementNode && slotNode.tagName === "SLOT-FB") {
595
+ if (getSlotChildSiblings(slotNode, getSlotName(slotNode), false).length) slotNode.hidden = true;
596
+ else slotNode.hidden = false;
597
+ }
547
598
  });
548
599
  let i = 0;
549
600
  for (i = 0; i < childNodes.length; i++) {
@@ -586,7 +637,7 @@ function getHostSlotNodes(childNodes, hostName, slotName) {
586
637
  slottedNodes.push(childNode);
587
638
  if (typeof slotName !== "undefined") return slottedNodes;
588
639
  }
589
- slottedNodes = [...slottedNodes, ...getHostSlotNodes(childNode.childNodes, hostName, slotName)];
640
+ slottedNodes = [...slottedNodes, ...getHostSlotNodes(internalCall(childNode, "childNodes"), hostName, slotName)];
590
641
  }
591
642
  return slottedNodes;
592
643
  }
@@ -617,7 +668,7 @@ const isNodeLocatedInSlot = (nodeToRelocate, slotName) => {
617
668
  if (nodeToRelocate.getAttribute("slot") === slotName) return true;
618
669
  return false;
619
670
  }
620
- if (nodeToRelocate["s-sn"] === slotName) return true;
671
+ if (typeof nodeToRelocate["s-sa"] === "string") return nodeToRelocate["s-sa"] === slotName;
621
672
  return slotName === "";
622
673
  };
623
674
  /**
@@ -666,8 +717,10 @@ function patchSlotNode(node) {
666
717
  const assignedFactory = (elementsOnly) => function(opts) {
667
718
  const toReturn = [];
668
719
  const slotName = this["s-sn"];
669
- if (opts?.flatten) if (BUILD.isDev) console.error("Flattening is not supported for Stencil non-shadow slots. You can use `.childNodes` for nested slot fallback content.");
670
- else console.error("Flattening not supported for Stencil non-shadow slots");
720
+ if (opts?.flatten) {
721
+ if (BUILD.isDev) console.error("Flattening is not supported for Stencil non-shadow slots. You can use `.childNodes` for nested slot fallback content.");
722
+ else console.error("Flattening not supported for Stencil non-shadow slots");
723
+ }
671
724
  const parent = this["s-cr"].parentElement;
672
725
  (parent.__childNodes ? parent.childNodes : getSlottedChildNodes(parent.childNodes)).forEach((n) => {
673
726
  if (slotName === getSlotName(n)) toReturn.push(n);
@@ -758,8 +811,10 @@ const patchCloneNode = (HostElementPrototype) => {
758
811
  for (; i < childNodes.length; i++) {
759
812
  slotted = childNodes[i]["s-nr"];
760
813
  nonStencilNode = stencilPrivates.every((privateField) => !childNodes[i][privateField]);
761
- if (slotted) if (clonedNode.__appendChild) clonedNode.__appendChild(slotted.cloneNode(true));
762
- else clonedNode.appendChild(slotted.cloneNode(true));
814
+ if (slotted) {
815
+ if (clonedNode.__appendChild) clonedNode.__appendChild(slotted.cloneNode(true));
816
+ else clonedNode.appendChild(slotted.cloneNode(true));
817
+ }
763
818
  if (nonStencilNode) clonedNode.appendChild(childNodes[i].cloneNode(true));
764
819
  }
765
820
  }
@@ -962,11 +1017,11 @@ const patchChildSlotNodes = (elm) => {
962
1017
  } });
963
1018
  patchHostOriginalAccessor("firstChild", elm);
964
1019
  Object.defineProperty(elm, "firstChild", { get() {
965
- return this.childNodes[0];
1020
+ return this.childNodes[0] || null;
966
1021
  } });
967
1022
  patchHostOriginalAccessor("lastChild", elm);
968
1023
  Object.defineProperty(elm, "lastChild", { get() {
969
- return this.childNodes[this.childNodes.length - 1];
1024
+ return this.childNodes[this.childNodes.length - 1] || null;
970
1025
  } });
971
1026
  patchHostOriginalAccessor("childNodes", elm);
972
1027
  Object.defineProperty(elm, "childNodes", { get() {
@@ -1012,7 +1067,7 @@ const patchNextSibling = (node) => {
1012
1067
  Object.defineProperty(node, "nextSibling", { get: function() {
1013
1068
  const parentNodes = this["s-ol"]?.parentNode.childNodes;
1014
1069
  const index = parentNodes?.indexOf(this);
1015
- if (parentNodes && index > -1) return parentNodes[index + 1];
1070
+ if (parentNodes && index > -1) return parentNodes[index + 1] || null;
1016
1071
  return this.__nextSibling;
1017
1072
  } });
1018
1073
  };
@@ -1027,7 +1082,7 @@ const patchNextElementSibling = (element) => {
1027
1082
  Object.defineProperty(element, "nextElementSibling", { get: function() {
1028
1083
  const parentEles = this["s-ol"]?.parentNode.children;
1029
1084
  const index = parentEles?.indexOf(this);
1030
- if (parentEles && index > -1) return parentEles[index + 1];
1085
+ if (parentEles && index > -1) return parentEles[index + 1] || null;
1031
1086
  return this.__nextElementSibling;
1032
1087
  } });
1033
1088
  };
@@ -1042,7 +1097,7 @@ const patchPreviousSibling = (node) => {
1042
1097
  Object.defineProperty(node, "previousSibling", { get: function() {
1043
1098
  const parentNodes = this["s-ol"]?.parentNode.childNodes;
1044
1099
  const index = parentNodes?.indexOf(this);
1045
- if (parentNodes && index > -1) return parentNodes[index - 1];
1100
+ if (parentNodes && index > -1) return parentNodes[index - 1] || null;
1046
1101
  return this.__previousSibling;
1047
1102
  } });
1048
1103
  };
@@ -1057,7 +1112,7 @@ const patchPreviousElementSibling = (element) => {
1057
1112
  Object.defineProperty(element, "previousElementSibling", { get: function() {
1058
1113
  const parentNodes = this["s-ol"]?.parentNode.children;
1059
1114
  const index = parentNodes?.indexOf(this);
1060
- if (parentNodes && index > -1) return parentNodes[index - 1];
1115
+ if (parentNodes && index > -1) return parentNodes[index - 1] || null;
1061
1116
  return this.__previousElementSibling;
1062
1117
  } });
1063
1118
  };
@@ -1232,7 +1287,7 @@ function queryNonceMetaTagContent(doc) {
1232
1287
  }
1233
1288
  //#endregion
1234
1289
  //#region src/runtime/styles.ts
1235
- const rootAppliedStyles = /* @__PURE__ */ new WeakMap();
1290
+ const rootAppliedStyles = /*@__PURE__*/ new WeakMap();
1236
1291
  /**
1237
1292
  * Get or initialize the set of applied style scope IDs for a container element.
1238
1293
  *
@@ -1256,9 +1311,10 @@ const getAppliedStyles = (container) => {
1256
1311
  * @param prepend if true, add to beginning; if false, add to end
1257
1312
  */
1258
1313
  const adoptStylesheet = (container, sheet, prepend = false) => {
1259
- if (supportsMutableAdoptedStyleSheets) if (prepend) container.adoptedStyleSheets.unshift(sheet);
1260
- else container.adoptedStyleSheets.push(sheet);
1261
- else if (prepend) container.adoptedStyleSheets = [sheet, ...container.adoptedStyleSheets];
1314
+ if (supportsMutableAdoptedStyleSheets) {
1315
+ if (prepend) container.adoptedStyleSheets.unshift(sheet);
1316
+ else container.adoptedStyleSheets.push(sheet);
1317
+ } else if (prepend) container.adoptedStyleSheets = [sheet, ...container.adoptedStyleSheets];
1262
1318
  else container.adoptedStyleSheets = [...container.adoptedStyleSheets, sheet];
1263
1319
  };
1264
1320
  /**
@@ -1271,7 +1327,7 @@ const adoptStylesheet = (container, sheet, prepend = false) => {
1271
1327
  * @returns a new CSSStyleSheet for the correct window
1272
1328
  */
1273
1329
  const createStylesheetForWindow = (container, cssText) => {
1274
- const sheet = new (container.defaultView ?? container.ownerDocument?.defaultView ?? win).CSSStyleSheet();
1330
+ const sheet = new (container.defaultView ?? (container.ownerDocument?.defaultView) ?? win).CSSStyleSheet();
1275
1331
  sheet.replaceSync(cssText);
1276
1332
  return sheet;
1277
1333
  };
@@ -1342,41 +1398,46 @@ const addStyle = (styleContainerNode, cmpMeta, mode) => {
1342
1398
  /**
1343
1399
  * attach styles at the end of the head tag if we render scoped components
1344
1400
  */
1345
- if (!(cmpMeta.$flags$ & CMP_FLAGS.shadowDomEncapsulation)) if (styleContainerNode.nodeName === "HEAD") {
1346
- /**
1347
- * if the page contains preconnect links, we want to insert the styles
1348
- * after the last preconnect link to ensure the styles are preloaded
1349
- */
1350
- const preconnectLinks = styleContainerNode.querySelectorAll("link[rel=preconnect]");
1351
- const referenceNode = preconnectLinks.length > 0 ? preconnectLinks[preconnectLinks.length - 1].nextSibling : styleContainerNode.querySelector("style");
1352
- styleContainerNode.insertBefore(styleElm, referenceNode?.parentNode === styleContainerNode ? referenceNode : null);
1353
- } else if ("host" in styleContainerNode) if (supportsConstructableStylesheets) {
1354
- const stylesheet = createStylesheetForWindow(styleContainerNode, style);
1355
- adoptStylesheet(styleContainerNode, stylesheet, true);
1356
- } else {
1357
- /**
1358
- * If a scoped component is used within a shadow root and constructable stylesheets are
1359
- * not supported, we want to insert the styles at the beginning of the shadow root node.
1360
- *
1361
- * However, if there is already a style node in the shadow root, we just append
1362
- * the styles to the existing node.
1363
- *
1364
- * Note: order of how styles are applied is important. The new style node
1365
- * should be inserted before the existing style node.
1366
- *
1367
- * During HMR, create separate style elements for scoped components so they can be
1368
- * updated independently without affecting other components' styles.
1369
- */
1370
- const existingStyleContainer = styleContainerNode.querySelector("style");
1371
- if (existingStyleContainer && !BUILD.hotModuleReplacement) existingStyleContainer.textContent = style + existingStyleContainer.textContent;
1372
- else styleContainerNode.prepend(styleElm);
1401
+ if (!(cmpMeta.$flags$ & CMP_FLAGS.shadowDomEncapsulation)) {
1402
+ if (styleContainerNode.nodeName === "HEAD") {
1403
+ /**
1404
+ * if the page contains preconnect links, we want to insert the styles
1405
+ * after the last preconnect link to ensure the styles are preloaded
1406
+ */
1407
+ const preconnectLinks = styleContainerNode.querySelectorAll("link[rel=preconnect]");
1408
+ const referenceNode = preconnectLinks.length > 0 ? preconnectLinks[preconnectLinks.length - 1].nextSibling : styleContainerNode.querySelector("style");
1409
+ styleContainerNode.insertBefore(styleElm, referenceNode?.parentNode === styleContainerNode ? referenceNode : null);
1410
+ } else if ("host" in styleContainerNode) {
1411
+ if (supportsConstructableStylesheets) {
1412
+ const stylesheet = createStylesheetForWindow(styleContainerNode, style);
1413
+ adoptStylesheet(styleContainerNode, stylesheet, true);
1414
+ } else {
1415
+ /**
1416
+ * If a scoped component is used within a shadow root and constructable stylesheets are
1417
+ * not supported, we want to insert the styles at the beginning of the shadow root node.
1418
+ *
1419
+ * However, if there is already a style node in the shadow root, we just append
1420
+ * the styles to the existing node.
1421
+ *
1422
+ * Note: order of how styles are applied is important. The new style node
1423
+ * should be inserted before the existing style node.
1424
+ *
1425
+ * During HMR, create separate style elements for scoped components so they can be
1426
+ * updated independently without affecting other components' styles.
1427
+ */
1428
+ const existingStyleContainer = styleContainerNode.querySelector("style");
1429
+ if (existingStyleContainer && !BUILD.hotModuleReplacement) existingStyleContainer.textContent = style + existingStyleContainer.textContent;
1430
+ else styleContainerNode.prepend(styleElm);
1431
+ }
1432
+ } else styleContainerNode.append(styleElm);
1373
1433
  }
1374
- else styleContainerNode.append(styleElm);
1375
1434
  /**
1376
1435
  * attach styles at the beginning of a shadow root node if we render shadow components
1377
1436
  */
1378
- if (cmpMeta.$flags$ & CMP_FLAGS.shadowDomEncapsulation) if (isClosedShadowSSR) styleContainerNode.prepend(styleElm);
1379
- else styleContainerNode.insertBefore(styleElm, null);
1437
+ if (cmpMeta.$flags$ & CMP_FLAGS.shadowDomEncapsulation) {
1438
+ if (isClosedShadowSSR) styleContainerNode.prepend(styleElm);
1439
+ else styleContainerNode.insertBefore(styleElm, null);
1440
+ }
1380
1441
  if (appliedStyles) appliedStyles.add(scopeId);
1381
1442
  }
1382
1443
  } else if (BUILD.constructableCSS) {
@@ -1468,7 +1529,12 @@ const hydrateScopedToShadow = () => {
1468
1529
  if (!win.document) return;
1469
1530
  const styleElements = win.document.querySelectorAll(`[${HYDRATED_STYLE_ID}]`);
1470
1531
  let i = 0;
1471
- for (; i < styleElements.length; i++) registerStyle(styleElements[i].getAttribute(HYDRATED_STYLE_ID), convertScopedToShadow(styleElements[i].innerHTML), true);
1532
+ for (; i < styleElements.length; i++) {
1533
+ const scopeId = styleElements[i].getAttribute(HYDRATED_STYLE_ID);
1534
+ const existing = styles.get(scopeId);
1535
+ const allowCS = existing !== void 0 ? existing instanceof CSSStyleSheet : true;
1536
+ registerStyle(scopeId, convertScopedToShadow(styleElements[i].innerHTML), allowCS);
1537
+ }
1472
1538
  };
1473
1539
  //#endregion
1474
1540
  //#region src/utils/helpers.ts
@@ -1600,11 +1666,15 @@ const setAccessor = (elm, memberName, oldValue, newValue, isSvg, flags, initialR
1600
1666
  }
1601
1667
  } else if (BUILD.vdomStyle && memberName === "style") {
1602
1668
  if (BUILD.updatable) {
1603
- for (const prop in oldValue) if (!newValue || newValue[prop] == null) if (!BUILD.hydrateServerSide && prop.includes("-")) elm.style.removeProperty(prop);
1604
- else elm.style[prop] = "";
1669
+ for (const prop in oldValue) if (!newValue || newValue[prop] == null) {
1670
+ if (!BUILD.hydrateServerSide && prop.includes("-")) elm.style.removeProperty(prop);
1671
+ else elm.style[prop] = "";
1672
+ }
1673
+ }
1674
+ for (const prop in newValue) if (!oldValue || newValue[prop] !== oldValue[prop]) {
1675
+ if (!BUILD.hydrateServerSide && prop.includes("-")) elm.style.setProperty(prop, newValue[prop]);
1676
+ else elm.style[prop] = newValue[prop];
1605
1677
  }
1606
- for (const prop in newValue) if (!oldValue || newValue[prop] !== oldValue[prop]) if (!BUILD.hydrateServerSide && prop.includes("-")) elm.style.setProperty(prop, newValue[prop]);
1607
- else elm.style[prop] = newValue[prop];
1608
1678
  } else if (BUILD.vdomKey && memberName === "key") {} else if (BUILD.vdomRef && memberName === "ref") {
1609
1679
  if (newValue) queueRefAttachment(newValue, elm);
1610
1680
  } else if (BUILD.vdomListener && (BUILD.lazyLoad ? !isProp : !elm.__lookupSetter__(memberName)) && memberName[0] === "o" && memberName[1] === "n") {
@@ -1613,11 +1683,11 @@ const setAccessor = (elm, memberName, oldValue, newValue, isSvg, flags, initialR
1613
1683
  else memberName = ln[2] + memberName.slice(3);
1614
1684
  if (oldValue || newValue) {
1615
1685
  const capture = memberName.endsWith(CAPTURE_EVENT_SUFFIX);
1616
- memberName = memberName.replace(/* @__PURE__ */ new RegExp(CAPTURE_EVENT_SUFFIX + "$"), "");
1686
+ memberName = memberName.replace(/*@__PURE__*/ new RegExp(CAPTURE_EVENT_SUFFIX + "$"), "");
1617
1687
  if (oldValue) plt.rel(elm, memberName, oldValue, capture);
1618
1688
  if (newValue) plt.ael(elm, memberName, newValue, capture);
1619
1689
  }
1620
- } else if (BUILD.vdomPropOrAttr && memberName[0] === "a" && memberName.startsWith("attr:")) {
1690
+ } else if (BUILD.vdomPropOrAttrPrefix && memberName[0] === "a" && memberName.startsWith("attr:")) {
1621
1691
  const propName = memberName.slice(5);
1622
1692
  let attrName;
1623
1693
  if (BUILD.member) {
@@ -1632,7 +1702,7 @@ const setAccessor = (elm, memberName, oldValue, newValue, isSvg, flags, initialR
1632
1702
  if (newValue !== false || elm.getAttribute(attrName) === "") elm.removeAttribute(attrName);
1633
1703
  } else elm.setAttribute(attrName, newValue === true ? "" : newValue);
1634
1704
  return;
1635
- } else if (BUILD.vdomPropOrAttr && memberName[0] === "p" && memberName.startsWith("prop:")) {
1705
+ } else if (BUILD.vdomPropOrAttrPrefix && memberName[0] === "p" && memberName.startsWith("prop:")) {
1636
1706
  const propName = memberName.slice(5);
1637
1707
  try {
1638
1708
  elm[propName] = newValue;
@@ -1652,8 +1722,10 @@ const setAccessor = (elm, memberName, oldValue, newValue, isSvg, flags, initialR
1652
1722
  if (!elm.tagName.includes("-")) {
1653
1723
  const n = newValue == null ? "" : newValue;
1654
1724
  if (memberName === "list") isProp = false;
1655
- else if (oldValue == null || elm[memberName] !== n) if (typeof elm.__lookupSetter__(memberName) === "function") elm[memberName] = n;
1656
- else elm.setAttribute(memberName, n);
1725
+ else if (oldValue == null || elm[memberName] !== n) {
1726
+ if (typeof elm.__lookupSetter__(memberName) === "function") elm[memberName] = n;
1727
+ else elm.setAttribute(memberName, n);
1728
+ }
1657
1729
  } else if (elm[memberName] !== newValue) elm[memberName] = newValue;
1658
1730
  } catch {}
1659
1731
  /**
@@ -1671,8 +1743,10 @@ const setAccessor = (elm, memberName, oldValue, newValue, isSvg, flags, initialR
1671
1743
  }
1672
1744
  }
1673
1745
  if (newValue == null || newValue === false) {
1674
- if (newValue !== false || elm.getAttribute(memberName) === "") if (BUILD.vdomXlink && xlink) elm.removeAttributeNS(XLINK_NS, memberName);
1675
- else elm.removeAttribute(memberName);
1746
+ if (newValue !== false || elm.getAttribute(memberName) === "" || flags & VNODE_FLAGS.isHost && !isEnumeratedAttribute(memberName)) {
1747
+ if (BUILD.vdomXlink && xlink) elm.removeAttributeNS(XLINK_NS, memberName);
1748
+ else elm.removeAttribute(memberName);
1749
+ }
1676
1750
  } else if ((!isProp || flags & VNODE_FLAGS.isHost || isSvg) && !isComplex && elm.nodeType === NODE_TYPE.ElementNode) {
1677
1751
  newValue = newValue === true ? "" : newValue;
1678
1752
  if (BUILD.vdomXlink && xlink) elm.setAttributeNS(XLINK_NS, memberName, newValue);
@@ -1680,6 +1754,18 @@ const setAccessor = (elm, memberName, oldValue, newValue, isSvg, flags, initialR
1680
1754
  }
1681
1755
  }
1682
1756
  };
1757
+ /**
1758
+ * Attribute names that are enumerated (tri-state true/false/unset) rather than
1759
+ * plain boolean-presence attributes. An explicit `"false"` string on one of
1760
+ * these is semantically different from the attribute being absent, so a
1761
+ * reflected `false` value must not clear a pre-existing literal value.
1762
+ */
1763
+ const ENUMERATED_ATTRIBUTES = /*@__PURE__*/ new Set([
1764
+ "draggable",
1765
+ "contenteditable",
1766
+ "spellcheck"
1767
+ ]);
1768
+ const isEnumeratedAttribute = (attrName) => ENUMERATED_ATTRIBUTES.has(attrName) || attrName.startsWith("aria-");
1683
1769
  const parseClassListRegex = /\s/;
1684
1770
  /**
1685
1771
  * Parsed a string of classnames into an array
@@ -1803,6 +1889,7 @@ const createElm = (oldParentVNode, newParentVNode, childIndex) => {
1803
1889
  }
1804
1890
  } else if (BUILD.slotRelocation && newVNode.$flags$ & VNODE_FLAGS.isSlotReference) {
1805
1891
  elm = newVNode.$elm$ = BUILD.isDebug || BUILD.hydrateServerSide ? slotReferenceDebugNode(newVNode) : win.document.createTextNode("");
1892
+ if (typeof newVNode.$attrs$?.slot === "string") elm["s-sa"] = newVNode.$attrs$.slot;
1806
1893
  if (BUILD.vdomAttribute) updateElement(null, newVNode, isSvgMode);
1807
1894
  } else {
1808
1895
  if (BUILD.svg && !isSvgMode) isSvgMode = newVNode.$tag$ === "svg";
@@ -2078,8 +2165,10 @@ const updateChildren = (parentElm, oldCh, newVNode, newCh, isInitialRender = fal
2078
2165
  node = createElm(oldCh && oldCh[newStartIdx], newVNode, newStartIdx);
2079
2166
  newStartVnode = newCh[++newStartIdx];
2080
2167
  }
2081
- if (node) if (BUILD.slotRelocation) insertBefore(referenceNode(oldStartVnode.$elm$).parentNode, node, referenceNode(oldStartVnode.$elm$));
2082
- else insertBefore(oldStartVnode.$elm$.parentNode, node, oldStartVnode.$elm$);
2168
+ if (node) {
2169
+ if (BUILD.slotRelocation) insertBefore(referenceNode(oldStartVnode.$elm$).parentNode, node, referenceNode(oldStartVnode.$elm$));
2170
+ else insertBefore(oldStartVnode.$elm$.parentNode, node, oldStartVnode.$elm$);
2171
+ }
2083
2172
  }
2084
2173
  if (oldStartIdx > oldEndIdx) addVnodes(parentElm, newCh[newEndIdx + 1] == null ? null : newCh[newEndIdx + 1].$elm$, newVNode, newCh, newStartIdx, newEndIdx);
2085
2174
  else if (BUILD.updatable && newStartIdx > newEndIdx) removeVnodes(oldCh, oldStartIdx, oldEndIdx);
@@ -2166,6 +2255,30 @@ const patch = (oldVNode, newVNode, isInitialRender = false) => {
2166
2255
  */
2167
2256
  const relocateNodes = [];
2168
2257
  /**
2258
+ * When a forwarded `<slot>` gets relocated, drag along any content already forwarded through it,
2259
+ * to wherever it just landed (or nowhere, to be hidden, if it didn't match anything).
2260
+ *
2261
+ * Runs as its own pass after {@link markSlotContentForRelocation} rather than inside it, so that
2262
+ * function's matching order - which hydration's node/comment ordering depends on - is untouched.
2263
+ */
2264
+ const carryContentWithRelocatedSlotRefs = () => {
2265
+ for (const relocateData of relocateNodes.slice()) {
2266
+ const marker = relocateData.$nodeToRelocate$;
2267
+ if (!marker["s-sr"]) continue;
2268
+ const carriedSiblings = getSlotChildSiblings(marker, marker["s-sn"] || "", false);
2269
+ for (const carriedSibling of carriedSiblings) {
2270
+ if (!carriedSibling["s-ol"]) continue;
2271
+ let siblingRelocateData = relocateNodes.find((r) => r.$nodeToRelocate$ === carriedSibling);
2272
+ if (!siblingRelocateData) {
2273
+ siblingRelocateData = { $nodeToRelocate$: carriedSibling };
2274
+ relocateNodes.push(siblingRelocateData);
2275
+ }
2276
+ siblingRelocateData.$slotRefNode$ = relocateData.$slotRefNode$;
2277
+ if (relocateData.$slotRefNode$) carriedSibling["s-sh"] = relocateData.$slotRefNode$["s-hn"];
2278
+ }
2279
+ }
2280
+ };
2281
+ /**
2169
2282
  * Mark the contents of a slot for relocation via adding references to them to
2170
2283
  * the {@link relocateNodes} data structure. The actual work of relocating them
2171
2284
  * will then be handled in {@link renderVdom}.
@@ -2270,7 +2383,7 @@ const insertBefore = (parent, newNode, reference, isInitialLoad) => {
2270
2383
  return newNode;
2271
2384
  }
2272
2385
  }
2273
- if (parent.__insertBefore) return parent.__insertBefore(newNode, reference);
2386
+ if (BUILD.slotRelocation && parent?.__insertBefore) return parent.__insertBefore(newNode, reference);
2274
2387
  else return parent?.insertBefore(newNode, reference);
2275
2388
  };
2276
2389
  /**
@@ -2364,6 +2477,7 @@ render() {
2364
2477
  plt.$flags$ |= PLATFORM_FLAGS.isTmpDisconnected;
2365
2478
  if (checkSlotRelocate) {
2366
2479
  markSlotContentForRelocation(rootVnode.$elm$);
2480
+ carryContentWithRelocatedSlotRefs();
2367
2481
  for (const relocateData of relocateNodes) {
2368
2482
  const nodeToRelocate = relocateData.$nodeToRelocate$;
2369
2483
  if (!nodeToRelocate["s-ol"] && win.document) {
@@ -2423,7 +2537,7 @@ render() {
2423
2537
  }
2424
2538
  if (BUILD.slotRelocation && !useNativeShadowDom && !(cmpMeta.$flags$ & CMP_FLAGS.shadowDomEncapsulation) && hostElm["s-cr"]) {
2425
2539
  const children = rootVnode.$elm$.__childNodes || rootVnode.$elm$.childNodes;
2426
- for (const childNode of children) if (childNode["s-hn"] !== hostTagName && !childNode["s-sh"]) {
2540
+ for (const childNode of children) if (childNode["s-hn"] !== hostTagName && childNode["s-sh"] !== hostTagName) {
2427
2541
  if (isInitialLoad && childNode["s-ih"] == null) childNode["s-ih"] = childNode.hidden ?? false;
2428
2542
  if (childNode.nodeType === NODE_TYPE.ElementNode) childNode.hidden = true;
2429
2543
  else if (childNode.nodeType === NODE_TYPE.TextNode && !!childNode.nodeValue.trim()) {
@@ -2441,16 +2555,58 @@ const slotReferenceDebugNode = (slotVNode) => win.document?.createComment(`<slot
2441
2555
  const originalLocationDebugNode = (nodeToRelocate) => win.document?.createComment(`org-location for ` + (nodeToRelocate.localName ? `<${nodeToRelocate.localName}> (host=${nodeToRelocate["s-hn"]})` : `[${nodeToRelocate.textContent}]`));
2442
2556
  //#endregion
2443
2557
  //#region src/runtime/update-component.ts
2558
+ /**
2559
+ * Get a promise that resolves once `hostRef`'s real `connectedCallback` has fired for the first time.
2560
+ *
2561
+ * @param hostRef the component's host reference
2562
+ * @returns a promise that resolves once the component's real `connectedCallback` has fired
2563
+ */
2564
+ const ensureFirstConnectPromise = (hostRef) => {
2565
+ if (!hostRef.$onFirstConnectPromise$) hostRef.$onFirstConnectPromise$ = new Promise((r) => hostRef.$onFirstConnectResolve$ = r);
2566
+ return hostRef.$onFirstConnectPromise$;
2567
+ };
2568
+ /**
2569
+ * Resolve `hostRef`'s first-connect promise and flag it connected. Called once this
2570
+ * component's real `connectedCallback` fires, plus from error/disconnect cleanup so a
2571
+ * component that never connects can't hang an ancestor or descendant forever.
2572
+ *
2573
+ * @param hostRef the component's host reference
2574
+ */
2575
+ const markFirstConnected = (hostRef) => {
2576
+ hostRef.$flags$ |= HOST_FLAGS.hasFiredConnected;
2577
+ hostRef.$onFirstConnectResolve$?.();
2578
+ hostRef.$onFirstConnectResolve$ = void 0;
2579
+ };
2580
+ /**
2581
+ * Wait for `ancestorElm` to be defined and its real `connectedCallback` to have completed.
2582
+ * Shared by the lazy ({@link initializeComponent}) and standalone (`bootstrap-standalone.ts`)
2583
+ * `connectedCallback` paths so a component never connects before its nearest Stencil
2584
+ * ancestor, regardless of load order. Both call sites already check `BUILD.asyncLoading` and
2585
+ * that an ancestor exists before calling this. Lazy's proxy classes are always pre-defined,
2586
+ * so the `whenDefined` wait is a no-op there - it only does real work for standalone's
2587
+ * autoloader, where the ancestor tag may not be defined yet.
2588
+ *
2589
+ * @param ancestorElm the nearest Stencil ancestor element
2590
+ */
2591
+ const awaitAncestorConnected = async (ancestorElm) => {
2592
+ let ancestorHostRef = getHostRef(ancestorElm);
2593
+ if (!BUILD.lazyLoad && !ancestorHostRef) {
2594
+ await getRegistry().whenDefined(ancestorElm.tagName.toLowerCase());
2595
+ ancestorHostRef = getHostRef(ancestorElm);
2596
+ }
2597
+ if (ancestorHostRef && !(ancestorHostRef.$flags$ & HOST_FLAGS.hasFiredConnected)) await ensureFirstConnectPromise(ancestorHostRef);
2598
+ };
2444
2599
  const attachToAncestor = (hostRef, ancestorComponent) => {
2445
2600
  if (BUILD.asyncLoading && ancestorComponent && !hostRef.$onRenderResolve$ && ancestorComponent["s-p"]) {
2446
2601
  const index = ancestorComponent["s-p"].push(new Promise((r) => hostRef.$onRenderResolve$ = () => {
2447
2602
  ancestorComponent["s-p"].splice(index - 1, 1);
2448
2603
  r();
2449
2604
  }));
2605
+ if (ancestorComponent["s-pc"]) ancestorComponent["s-pc"].push(ensureFirstConnectPromise(hostRef));
2450
2606
  }
2451
2607
  };
2452
2608
  const scheduleUpdate = (hostRef, isInitialLoad) => {
2453
- if (BUILD.taskQueue && BUILD.updatable) hostRef.$flags$ |= HOST_FLAGS.isQueuedForUpdate;
2609
+ if (BUILD.updatable) hostRef.$flags$ |= HOST_FLAGS.isQueuedForUpdate;
2454
2610
  if (BUILD.asyncLoading && hostRef.$flags$ & HOST_FLAGS.isWaitingForChildren) {
2455
2611
  hostRef.$flags$ |= HOST_FLAGS.needsRerender;
2456
2612
  return;
@@ -2458,6 +2614,8 @@ const scheduleUpdate = (hostRef, isInitialLoad) => {
2458
2614
  attachToAncestor(hostRef, hostRef.$ancestorComponent$);
2459
2615
  const dispatch = () => dispatchHooks(hostRef, isInitialLoad);
2460
2616
  if (isInitialLoad) {
2617
+ const pendingConnects = BUILD.asyncLoading ? hostRef.$hostElement$["s-pc"] : void 0;
2618
+ if (pendingConnects && pendingConnects.length > 0) return Promise.all(pendingConnects).then(dispatch).catch(dispatch);
2461
2619
  queueMicrotask(() => {
2462
2620
  dispatch();
2463
2621
  });
@@ -2497,10 +2655,6 @@ const dispatchHooks = (hostRef, isInitialLoad) => {
2497
2655
  let maybePromise;
2498
2656
  if (isInitialLoad) {
2499
2657
  if (BUILD.lazyLoad) {
2500
- if (BUILD.slotRelocation && hostRef.$deferredConnectedCallback$) {
2501
- hostRef.$deferredConnectedCallback$ = false;
2502
- safeCall(instance, "connectedCallback", void 0, elm);
2503
- }
2504
2658
  if (BUILD.hostListener) {
2505
2659
  hostRef.$flags$ |= HOST_FLAGS.isListenReady;
2506
2660
  if (hostRef.$queuedListeners$) {
@@ -2513,6 +2667,14 @@ const dispatchHooks = (hostRef, isInitialLoad) => {
2513
2667
  if (BUILD.lifecycleDOMEvents) emitLifecycleEvent(elm, "componentWillLoad");
2514
2668
  maybePromise = safeCall(instance, "componentWillLoad", void 0, elm);
2515
2669
  } else {
2670
+ if (BUILD.updatable && hostRef.$queuedPropChanges$) {
2671
+ const changes = hostRef.$queuedPropChanges$;
2672
+ hostRef.$queuedPropChanges$ = void 0;
2673
+ if (safeCall(instance, "componentShouldUpdate", changes, elm) === false) {
2674
+ hostRef.$flags$ &= ~HOST_FLAGS.isQueuedForUpdate;
2675
+ return;
2676
+ }
2677
+ }
2516
2678
  if (BUILD.lifecycleDOMEvents) emitLifecycleEvent(elm, "componentWillUpdate");
2517
2679
  maybePromise = safeCall(instance, "componentWillUpdate", void 0, elm);
2518
2680
  }
@@ -2627,7 +2789,6 @@ let renderingRef = null;
2627
2789
  const callRender = (hostRef, instance, elm, isInitialLoad) => {
2628
2790
  const allRenderFn = !!BUILD.allRenderFn;
2629
2791
  const lazyLoad = !!BUILD.lazyLoad;
2630
- const taskQueue = !!BUILD.taskQueue;
2631
2792
  const updatable = !!BUILD.updatable;
2632
2793
  try {
2633
2794
  renderingRef = instance;
@@ -2636,14 +2797,17 @@ const callRender = (hostRef, instance, elm, isInitialLoad) => {
2636
2797
  * method, so we can call the method immediately. If not, check before calling it.
2637
2798
  */
2638
2799
  instance = allRenderFn ? instance.render() : instance.render && instance.render();
2639
- if (updatable && taskQueue) hostRef.$flags$ &= ~HOST_FLAGS.isQueuedForUpdate;
2800
+ if (updatable) hostRef.$flags$ &= ~HOST_FLAGS.isQueuedForUpdate;
2640
2801
  if (updatable || lazyLoad) hostRef.$flags$ |= HOST_FLAGS.hasRendered;
2641
- if (BUILD.hasRenderFn || BUILD.reflect) if (BUILD.vdomRender || BUILD.reflect) if (BUILD.hydrateServerSide) return Promise.resolve(instance).then((value) => renderVdom(hostRef, value, isInitialLoad));
2642
- else renderVdom(hostRef, instance, isInitialLoad);
2643
- else {
2644
- const shadowRoot = elm.shadowRoot;
2645
- if (hostRef.$cmpMeta$.$flags$ & CMP_FLAGS.shadowDomEncapsulation) shadowRoot.textContent = instance;
2646
- else elm.textContent = instance;
2802
+ if (BUILD.hasRenderFn || BUILD.reflect) {
2803
+ if (BUILD.vdomRender || BUILD.reflect) {
2804
+ if (BUILD.hydrateServerSide) return Promise.resolve(instance).then((value) => renderVdom(hostRef, value, isInitialLoad));
2805
+ else renderVdom(hostRef, instance, isInitialLoad);
2806
+ } else {
2807
+ const shadowRoot = elm.shadowRoot;
2808
+ if (hostRef.$cmpMeta$.$flags$ & CMP_FLAGS.shadowDomEncapsulation) shadowRoot.textContent = instance;
2809
+ else elm.textContent = instance;
2810
+ }
2647
2811
  }
2648
2812
  } catch (e) {
2649
2813
  consoleError(e, hostRef.$hostElement$);
@@ -2783,17 +2947,19 @@ const initializeSignals = (elm, hostRef, cmpMeta) => {
2783
2947
  const instance = BUILD.lazyLoad ? hostRef.$lazyInstance$ : elm;
2784
2948
  for (const [memberName, [memberFlags]] of Object.entries(cmpMeta.$members$ ?? {})) {
2785
2949
  if (!(memberFlags & MEMBER_FLAGS.PropLike)) continue;
2786
- const sig = signal(hostRef.$instanceValues$.get(memberName));
2950
+ const initialVal = hostRef.$instanceValues$.get(memberName);
2951
+ const sig = signal(initialVal);
2787
2952
  hostRef.$signalValues$.set(memberName, sig);
2788
2953
  let prevScheduleVal = sig.peek();
2789
2954
  disposers.push(effect(() => {
2790
2955
  const newVal = sig.value;
2791
2956
  if (hostRef.$flags$ & HOST_FLAGS.hasRendered) {
2792
2957
  if (instance?.componentShouldUpdate) {
2793
- if (instance.componentShouldUpdate(newVal, prevScheduleVal, memberName) === false && !(hostRef.$flags$ & HOST_FLAGS.isQueuedForUpdate)) {
2794
- prevScheduleVal = newVal;
2795
- return;
2796
- }
2958
+ const changes = hostRef.$queuedPropChanges$ ||= {};
2959
+ changes[memberName] = {
2960
+ newVal,
2961
+ oldVal: changes[memberName]?.oldVal ?? prevScheduleVal
2962
+ };
2797
2963
  }
2798
2964
  if (!(hostRef.$flags$ & HOST_FLAGS.isQueuedForUpdate)) scheduleUpdate(hostRef, false);
2799
2965
  }
@@ -2828,7 +2994,8 @@ const initializeSignals = (elm, hostRef, cmpMeta) => {
2828
2994
  consoleError(e, elm);
2829
2995
  }
2830
2996
  }));
2831
- elm[STENCIL_SIGNALS_SYMBOL] = new Map([...hostRef.$signalValues$].filter(([k]) => (cmpMeta.$members$?.[k]?.[0] ?? 0) & MEMBER_FLAGS.Prop));
2997
+ const publicSignals = new Map([...hostRef.$signalValues$].filter(([k]) => (cmpMeta.$members$?.[k]?.[0] ?? 0) & MEMBER_FLAGS.Prop));
2998
+ elm[STENCIL_SIGNALS_SYMBOL] = publicSignals;
2832
2999
  hostRef.$signalCleanup$ = () => {
2833
3000
  disposers.forEach((d) => d());
2834
3001
  elm[STENCIL_SIGNALS_SYMBOL] = void 0;
@@ -2877,24 +3044,30 @@ const h = (nodeName, vnodeData, ...children) => {
2877
3044
  for (let i = 0; i < c.length; i++) {
2878
3045
  child = c[i];
2879
3046
  if (Array.isArray(child)) walk(child);
2880
- else if (child != null && typeof child !== "boolean") if (BUILD.vdomSignals && isSignalLike(child)) {
2881
- const sigVNode = newVNode(null, String(child.peek()));
2882
- sigVNode.$signal$ = child;
2883
- vNodeChildren.push(sigVNode);
2884
- lastSimple = false;
2885
- } else {
2886
- if (simple = typeof nodeName !== "function" && !isComplexType(child)) child = String(child);
2887
- else if (BUILD.isDev && typeof nodeName !== "function" && child.$flags$ === void 0) consoleDevError(`vNode passed as children has unexpected type.
2888
- Make sure it's using the correct h() function.
2889
- Empty objects can also be the cause, look for JSX comments that became objects.`);
2890
- if (simple && lastSimple) vNodeChildren[vNodeChildren.length - 1].$text$ += child;
2891
- else vNodeChildren.push(simple ? newVNode(null, child) : child);
2892
- lastSimple = simple;
3047
+ else if (child != null && typeof child !== "boolean") {
3048
+ if (BUILD.vdomSignals && isSignalLike(child)) {
3049
+ const sigVNode = newVNode(null, String(child.peek()));
3050
+ sigVNode.$signal$ = child;
3051
+ vNodeChildren.push(sigVNode);
3052
+ lastSimple = false;
3053
+ } else {
3054
+ if (simple = typeof nodeName !== "function" && !isComplexType(child)) child = String(child);
3055
+ else if (typeof nodeName !== "function" && child.$flags$ === void 0) {
3056
+ if (BUILD.isDev) consoleDevError(`vNode passed as children has unexpected type.
3057
+ Make sure it's using the correct h() function.
3058
+ Empty objects can also be the cause, look for JSX comments that became objects.`);
3059
+ else consoleError("Invalid vNode child");
3060
+ continue;
3061
+ }
3062
+ if (simple && lastSimple) vNodeChildren[vNodeChildren.length - 1].$text$ += child;
3063
+ else vNodeChildren.push(simple ? newVNode(null, child) : child);
3064
+ lastSimple = simple;
3065
+ }
2893
3066
  }
2894
3067
  }
2895
3068
  };
2896
3069
  walk(children);
2897
- if (vnodeData) {
3070
+ if (vnodeData && typeof vnodeData === "object") {
2898
3071
  if (BUILD.isDev && nodeName === "input") validateInputProperties(vnodeData);
2899
3072
  if (BUILD.vdomKey && vnodeData.key) key = vnodeData.key;
2900
3073
  if (BUILD.slotRelocation && vnodeData.name) slotName = vnodeData.name;
@@ -2995,7 +3168,7 @@ const convertToPrivate = (node) => {
2995
3168
  /**
2996
3169
  * Validates the ordering of attributes on an input element
2997
3170
  *
2998
- * @param inputElm the element to validate
3171
+ * @param inputElm the vnode data (JSX props) for the element to validate
2999
3172
  */
3000
3173
  const validateInputProperties = (inputElm) => {
3001
3174
  const props = Object.keys(inputElm);
@@ -3874,14 +4047,15 @@ const parsePropertyValue = (propValue, propType, isFormAssociated) => {
3874
4047
  /**
3875
4048
  * ensure this value is of the correct prop type
3876
4049
  */
3877
- if (BUILD.propBoolean && propType & MEMBER_FLAGS.Boolean)
3878
- /**
3879
- * For form-associated components, according to HTML spec, the presence of any boolean attribute
3880
- * (regardless of its value, even "false") should make the property true.
3881
- * For non-form-associated components, we maintain the legacy behavior where "false" becomes false.
3882
- */
3883
- if (BUILD.formAssociated && isFormAssociated && typeof propValue === "string") return propValue === "" || !!propValue;
3884
- else return propValue === "false" ? false : propValue === "" || !!propValue;
4050
+ if (BUILD.propBoolean && propType & MEMBER_FLAGS.Boolean) {
4051
+ /**
4052
+ * For form-associated components, according to HTML spec, the presence of any boolean attribute
4053
+ * (regardless of its value, even "false") should make the property true.
4054
+ * For non-form-associated components, we maintain the legacy behavior where "false" becomes false.
4055
+ */
4056
+ if (BUILD.formAssociated && isFormAssociated && typeof propValue === "string") return propValue === "" || !!propValue;
4057
+ else return propValue === "false" ? false : propValue === "" || !!propValue;
4058
+ }
3885
4059
  /**
3886
4060
  * force it to be a number
3887
4061
  */
@@ -3969,7 +4143,11 @@ const setValue = (ref, propName, newVal, cmpMeta) => {
3969
4143
  }
3970
4144
  if (BUILD.updatable && flags & HOST_FLAGS.hasRendered) {
3971
4145
  if (instance.componentShouldUpdate) {
3972
- if (instance.componentShouldUpdate(newVal, oldVal, propName) === false && !(flags & HOST_FLAGS.isQueuedForUpdate)) return;
4146
+ const changes = hostRef.$queuedPropChanges$ ||= {};
4147
+ changes[propName] = {
4148
+ newVal,
4149
+ oldVal: changes[propName]?.oldVal ?? oldVal
4150
+ };
3973
4151
  }
3974
4152
  if (!(flags & HOST_FLAGS.isQueuedForUpdate)) scheduleUpdate(hostRef, false);
3975
4153
  }
@@ -4103,11 +4281,12 @@ const proxyComponent = (Cstr, cmpMeta, flags) => {
4103
4281
  };
4104
4282
  for (const deserializer of cmpMeta.$deserializers$[propName]) {
4105
4283
  const [[methodName]] = Object.entries(deserializer);
4106
- if (BUILD.lazyLoad) if (hostRef.$lazyInstance$) setVal(methodName, hostRef.$lazyInstance$);
4107
- else hostRef.$fetchedCbList$.push(() => {
4108
- setVal(methodName, hostRef.$lazyInstance$);
4109
- });
4110
- else setVal(methodName, this);
4284
+ if (BUILD.lazyLoad) {
4285
+ if (hostRef.$lazyInstance$) setVal(methodName, hostRef.$lazyInstance$);
4286
+ else hostRef.$fetchedCbList$.push(() => {
4287
+ setVal(methodName, hostRef.$lazyInstance$);
4288
+ });
4289
+ } else setVal(methodName, this);
4111
4290
  }
4112
4291
  return;
4113
4292
  } else if (prototype.hasOwnProperty(propName) && typeof this[propName] === "number" && this[propName] == newValue) return;
@@ -4131,7 +4310,7 @@ const proxyComponent = (Cstr, cmpMeta, flags) => {
4131
4310
  if (!isSpuriousBooleanRemoval && newValue != this[propName] && (!propDesc.get || !!propDesc.set)) this[propName] = newValue;
4132
4311
  });
4133
4312
  };
4134
- Cstr.observedAttributes = Array.from(new Set([...Object.keys(cmpMeta.$watchers$ ?? {}), ...members.filter(([_, m]) => m[0] & MEMBER_FLAGS.HasAttribute).map(([propName, m]) => {
4313
+ Cstr.observedAttributes = Array.from(/* @__PURE__ */ new Set([...Object.keys(cmpMeta.$watchers$ ?? {}), ...members.filter(([_, m]) => m[0] & MEMBER_FLAGS.HasAttribute).map(([propName, m]) => {
4135
4314
  const attrName = m[1] || propName;
4136
4315
  attrNameToPropName.set(attrName, propName);
4137
4316
  if (BUILD.reflect && m[0] & MEMBER_FLAGS.ReflectAttr) cmpMeta.$attrsToReflect$?.push([propName, attrName]);
@@ -4158,6 +4337,7 @@ const initializeComponent = async (elm, hostRef, cmpMeta, hmrVersionId) => {
4158
4337
  try {
4159
4338
  if ((hostRef.$flags$ & HOST_FLAGS.hasInitializedComponent) === 0) {
4160
4339
  hostRef.$flags$ |= HOST_FLAGS.hasInitializedComponent;
4340
+ hostRef.$flags$ &= ~HOST_FLAGS.hasFailedLoad;
4161
4341
  const bundleId = cmpMeta.$lazyBundleId$;
4162
4342
  if (BUILD.lazyLoad && bundleId) {
4163
4343
  const CstrImport = loadModule(cmpMeta, hostRef, hmrVersionId);
@@ -4166,7 +4346,12 @@ const initializeComponent = async (elm, hostRef, cmpMeta, hmrVersionId) => {
4166
4346
  Cstr = await CstrImport;
4167
4347
  endLoad();
4168
4348
  } else Cstr = CstrImport;
4169
- if (!Cstr) throw new Error(`Constructor for "${cmpMeta.$tagName$}#${hostRef.$modeName$}" was not found`);
4349
+ if (!Cstr) {
4350
+ hostRef.$flags$ &= ~HOST_FLAGS.hasInitializedComponent;
4351
+ hostRef.$loadRetryCount$ = (hostRef.$loadRetryCount$ ?? 0) + 1;
4352
+ if (hostRef.$loadRetryCount$ < 3) hostRef.$flags$ |= HOST_FLAGS.hasFailedLoad;
4353
+ throw new Error(`Constructor for "${cmpMeta.$tagName$}#${hostRef.$modeName$}" was not found`);
4354
+ }
4170
4355
  if (BUILD.member && !Cstr.isProxied) {
4171
4356
  if (BUILD.propChangeCallback) {
4172
4357
  cmpMeta.$watchers$ = normalizeWatchers(Cstr.watchers);
@@ -4185,8 +4370,14 @@ const initializeComponent = async (elm, hostRef, cmpMeta, hmrVersionId) => {
4185
4370
  }
4186
4371
  if (BUILD.member) hostRef.$flags$ &= ~HOST_FLAGS.isConstructingInstance;
4187
4372
  endNewInstance();
4188
- if (!(BUILD.slotRelocation && cmpMeta.$flags$ & CMP_FLAGS.hasSlotRelocation)) fireConnectedCallback(hostRef.$lazyInstance$, elm);
4189
- else hostRef.$deferredConnectedCallback$ = true;
4373
+ if (BUILD.asyncLoading && hostRef.$ancestorComponent$) await awaitAncestorConnected(hostRef.$ancestorComponent$);
4374
+ if (!(BUILD.slotRelocation && cmpMeta.$flags$ & CMP_FLAGS.hasSlotRelocation)) {
4375
+ fireConnectedCallback(hostRef.$lazyInstance$, elm);
4376
+ if (BUILD.asyncLoading) markFirstConnected(hostRef);
4377
+ } else queueMicrotask(() => {
4378
+ fireConnectedCallback(hostRef.$lazyInstance$, elm);
4379
+ if (BUILD.asyncLoading) markFirstConnected(hostRef);
4380
+ });
4190
4381
  } else Cstr = elm.constructor;
4191
4382
  if (BUILD.style && Cstr && Cstr.style) {
4192
4383
  /**
@@ -4245,7 +4436,8 @@ const initializeComponent = async (elm, hostRef, cmpMeta, hmrVersionId) => {
4245
4436
  hostRef.$onRenderResolve$();
4246
4437
  hostRef.$onRenderResolve$ = void 0;
4247
4438
  }
4248
- if (BUILD.asyncLoading && hostRef.$onReadyResolve$) hostRef.$onReadyResolve$(elm);
4439
+ if (BUILD.asyncLoading) markFirstConnected(hostRef);
4440
+ if (BUILD.asyncLoading && hostRef.$onReadyResolve$ && !(hostRef.$flags$ & HOST_FLAGS.hasFailedLoad)) hostRef.$onReadyResolve$(elm);
4249
4441
  }
4250
4442
  };
4251
4443
  const fireConnectedCallback = (instance, elm) => {
@@ -4308,6 +4500,7 @@ const connectedCallback = (elm) => {
4308
4500
  } else {
4309
4501
  addHostEventListeners(elm, hostRef, cmpMeta.$listeners$);
4310
4502
  if (hostRef?.$lazyInstance$) fireConnectedCallback(hostRef.$lazyInstance$, elm);
4503
+ else if (hostRef.$flags$ & HOST_FLAGS.hasFailedLoad) setTimeout(() => initializeComponent(elm, hostRef, cmpMeta), LAZY_LOAD_RETRY_INTERVAL_MS);
4311
4504
  else if (hostRef?.$onReadyPromise$) hostRef.$onReadyPromise$.then(() => fireConnectedCallback(hostRef.$lazyInstance$, elm));
4312
4505
  }
4313
4506
  endConnected();
@@ -4337,6 +4530,7 @@ const disconnectedCallback = async (elm) => {
4337
4530
  hostRef.$signalCleanup$();
4338
4531
  hostRef.$signalCleanup$ = void 0;
4339
4532
  }
4533
+ if (BUILD.asyncLoading && hostRef && !(hostRef.$flags$ & HOST_FLAGS.hasFiredConnected)) markFirstConnected(hostRef);
4340
4534
  if (!BUILD.lazyLoad) disconnectInstance(elm);
4341
4535
  else if (hostRef?.$lazyInstance$) disconnectInstance(hostRef.$lazyInstance$, elm);
4342
4536
  else if (hostRef?.$onReadyPromise$) hostRef.$onReadyPromise$.then(() => disconnectInstance(hostRef.$lazyInstance$, elm));
@@ -4384,7 +4578,6 @@ const hmrStart = (hostElement, cmpMeta, hmrVersionId) => {
4384
4578
  };
4385
4579
  const hmrStandalone = async (hostElement, cmpMeta, hmrVersionId) => {
4386
4580
  const modulePath = hostElement.constructor.__stencil_module__;
4387
- console.log(`[Stencil HMR] hmrStandalone <${cmpMeta.$tagName$}> modulePath:`, modulePath);
4388
4581
  if (!modulePath) {
4389
4582
  console.warn(`[Stencil HMR] No __stencil_module__ on <${cmpMeta.$tagName$}> constructor - was this built with devMode?`);
4390
4583
  return;
@@ -4397,18 +4590,39 @@ const hmrStandalone = async (hostElement, cmpMeta, hmrVersionId) => {
4397
4590
  const NewClass = Object.values(newModule).find((v) => typeof v === "function" && v.is === cmpMeta.$tagName$) ?? newModule.default;
4398
4591
  if (!NewClass) return;
4399
4592
  const ctor = customElements.get(cmpMeta.$tagName$);
4400
- if (ctor) for (const key of Object.getOwnPropertyNames(NewClass.prototype)) {
4401
- if (key === "constructor") continue;
4402
- Object.defineProperty(ctor.prototype, key, Object.getOwnPropertyDescriptor(NewClass.prototype, key));
4593
+ if (ctor) {
4594
+ for (const key of Object.getOwnPropertyNames(NewClass.prototype)) {
4595
+ if (key === "constructor") continue;
4596
+ Object.defineProperty(ctor.prototype, key, Object.getOwnPropertyDescriptor(NewClass.prototype, key));
4597
+ }
4598
+ const styleDesc = Object.getOwnPropertyDescriptor(NewClass, "style");
4599
+ if (styleDesc) {
4600
+ Object.defineProperty(ctor, "style", styleDesc);
4601
+ const newStyle = NewClass.style;
4602
+ if (newStyle) {
4603
+ const scopeId = getScopeId(cmpMeta);
4604
+ const isShadow = !!(cmpMeta.$flags$ & CMP_FLAGS.shadowDomEncapsulation);
4605
+ console.log("[stencil-hmr] registerStyle", {
4606
+ tag: cmpMeta.$tagName$,
4607
+ scopeId,
4608
+ isShadow,
4609
+ cssLen: newStyle.length
4610
+ });
4611
+ registerStyle(scopeId, newStyle, isShadow);
4612
+ }
4613
+ }
4403
4614
  }
4615
+ const isShadow = !!(cmpMeta.$flags$ & CMP_FLAGS.shadowDomEncapsulation);
4404
4616
  document.querySelectorAll(cmpMeta.$tagName$).forEach((el) => {
4405
- if (BUILD.hostListener) {
4406
- const hostRef = getHostRef(el);
4407
- if (hostRef?.$rmListeners$) {
4408
- hostRef.$rmListeners$.map((rmListener) => rmListener());
4409
- hostRef.$rmListeners$ = void 0;
4410
- addHostEventListeners(el, hostRef, cmpMeta.$listeners$);
4411
- }
4617
+ const hostRef = getHostRef(el);
4618
+ if (BUILD.hostListener && hostRef?.$rmListeners$) {
4619
+ hostRef.$rmListeners$.map((rmListener) => rmListener());
4620
+ hostRef.$rmListeners$ = void 0;
4621
+ addHostEventListeners(el, hostRef, cmpMeta.$listeners$);
4622
+ }
4623
+ if (!isShadow && hostRef) {
4624
+ console.log("[stencil-hmr] calling attachStyles for", cmpMeta.$tagName$);
4625
+ attachStyles(hostRef);
4412
4626
  }
4413
4627
  forceUpdate(el);
4414
4628
  });
@@ -4419,7 +4633,9 @@ const hmrStandalone = async (hostElement, cmpMeta, hmrVersionId) => {
4419
4633
  //#endregion
4420
4634
  //#region src/runtime/bootstrap-standalone.ts
4421
4635
  const defineCustomElement = (Cstr, compactMeta) => {
4422
- customElements.define(transformTag(compactMeta[1]), proxyCustomElement(Cstr, compactMeta));
4636
+ const tag = transformTag(compactMeta[1]);
4637
+ const proxied = proxyCustomElement(Cstr, compactMeta);
4638
+ if (!customElements.get(tag)) customElements.define(tag, proxied);
4423
4639
  };
4424
4640
  const proxyCustomElement = (Cstr, compactMeta) => {
4425
4641
  if (BUILD.profile && performance.mark && performance.getEntriesByName("st:app:start", "mark").length === 0) performance.mark("st:app:start");
@@ -4440,18 +4656,20 @@ const proxyCustomElement = (Cstr, compactMeta) => {
4440
4656
  hmrStart(this, cmpMeta, hmrVersionId);
4441
4657
  };
4442
4658
  if (!(cmpMeta.$flags$ & CMP_FLAGS.shadowDomEncapsulation) && (BUILD.slotCloneNode || BUILD.patchClone && cmpMeta.$flags$ & CMP_FLAGS.patchClone)) patchCloneNode(Cstr.prototype);
4443
- if (!(cmpMeta.$flags$ & CMP_FLAGS.shadowDomEncapsulation) && cmpMeta.$flags$ & CMP_FLAGS.hasSlot) if (BUILD.lightDomPatches || BUILD.patchAll && cmpMeta.$flags$ & CMP_FLAGS.patchAll) applyLightDomPatches(Cstr.prototype);
4444
- else {
4445
- if (BUILD.slotChildNodes || BUILD.patchChildren && cmpMeta.$flags$ & CMP_FLAGS.patchChildren) patchChildSlotNodes(Cstr.prototype);
4446
- if (BUILD.slotDomMutations || BUILD.patchInsert && cmpMeta.$flags$ & CMP_FLAGS.patchInsert) {
4447
- patchSlotAppendChild(Cstr.prototype);
4448
- patchSlotAppend(Cstr.prototype);
4449
- patchSlotPrepend(Cstr.prototype);
4450
- patchSlotInsertAdjacentHTML(Cstr.prototype);
4451
- patchInsertBefore(Cstr.prototype);
4452
- patchSlotRemoveChild(Cstr.prototype);
4659
+ if (!(cmpMeta.$flags$ & CMP_FLAGS.shadowDomEncapsulation) && cmpMeta.$flags$ & CMP_FLAGS.hasSlot) {
4660
+ if (BUILD.lightDomPatches || BUILD.patchAll && cmpMeta.$flags$ & CMP_FLAGS.patchAll) applyLightDomPatches(Cstr.prototype);
4661
+ else {
4662
+ if (BUILD.slotChildNodes || BUILD.patchChildren && cmpMeta.$flags$ & CMP_FLAGS.patchChildren) patchChildSlotNodes(Cstr.prototype);
4663
+ if (BUILD.slotDomMutations || BUILD.patchInsert && cmpMeta.$flags$ & CMP_FLAGS.patchInsert) {
4664
+ patchSlotAppendChild(Cstr.prototype);
4665
+ patchSlotAppend(Cstr.prototype);
4666
+ patchSlotPrepend(Cstr.prototype);
4667
+ patchSlotInsertAdjacentHTML(Cstr.prototype);
4668
+ patchInsertBefore(Cstr.prototype);
4669
+ patchSlotRemoveChild(Cstr.prototype);
4670
+ }
4671
+ if (BUILD.slotTextContent) patchTextContent(Cstr.prototype);
4453
4672
  }
4454
- if (BUILD.slotTextContent) patchTextContent(Cstr.prototype);
4455
4673
  }
4456
4674
  if (BUILD.hydrateClientSide && BUILD.shadowDom) hydrateScopedToShadow();
4457
4675
  const originalConnectedCallback = Cstr.prototype.connectedCallback;
@@ -4464,19 +4682,26 @@ const proxyCustomElement = (Cstr, compactMeta) => {
4464
4682
  componentOnReady() {
4465
4683
  return getHostRef(this)?.$onReadyPromise$;
4466
4684
  },
4467
- connectedCallback() {
4468
- if (!this.__hasHostListenerAttached) {
4469
- const hostRef = getHostRef(this);
4685
+ async connectedCallback() {
4686
+ const isFirstConnect = !this.__hasHostListenerAttached;
4687
+ let hostRef;
4688
+ if (isFirstConnect) {
4689
+ hostRef = getHostRef(this);
4470
4690
  if (!hostRef) return;
4471
4691
  addHostEventListeners(this, hostRef, cmpMeta.$listeners$);
4472
4692
  this.__hasHostListenerAttached = true;
4473
4693
  }
4474
4694
  connectedCallback(this);
4475
- if (originalConnectedCallback) originalConnectedCallback.call(this);
4695
+ if (BUILD.asyncLoading && hostRef && hostRef.$ancestorComponent$) {
4696
+ await awaitAncestorConnected(hostRef.$ancestorComponent$);
4697
+ if (!this.isConnected) return;
4698
+ }
4699
+ if (originalConnectedCallback && (plt.$flags$ & PLATFORM_FLAGS.isTmpDisconnected) === 0) originalConnectedCallback.call(this);
4700
+ if (BUILD.asyncLoading && hostRef) markFirstConnected(hostRef);
4476
4701
  },
4477
4702
  disconnectedCallback() {
4478
4703
  disconnectedCallback(this);
4479
- if (originalDisconnectedCallback) originalDisconnectedCallback.call(this);
4704
+ if (originalDisconnectedCallback && (plt.$flags$ & PLATFORM_FLAGS.isTmpDisconnected) === 0) originalDisconnectedCallback.call(this);
4480
4705
  },
4481
4706
  __attachShadow() {
4482
4707
  const isClosed = BUILD.shadowModeClosed && !!(cmpMeta.$flags$ & CMP_FLAGS.shadowModeClosed);
@@ -4530,8 +4755,8 @@ const bootstrapLazy = (lazyBundles, options = {}) => {
4530
4755
  const exclude = options.exclude || [];
4531
4756
  const _reg = options.registry ?? getRegistry();
4532
4757
  const head = win.document.head;
4533
- const metaCharset = /* @__PURE__ */ head.querySelector("meta[charset]");
4534
- const dataStyles = /* @__PURE__ */ win.document.createElement("style");
4758
+ const metaCharset = /*@__PURE__*/ head.querySelector("meta[charset]");
4759
+ const dataStyles = /*@__PURE__*/ win.document.createElement("style");
4535
4760
  const deferredConnectedCallbacks = [];
4536
4761
  let appLoadFallback;
4537
4762
  let isBootstrapping = true;
@@ -4599,8 +4824,11 @@ const bootstrapLazy = (lazyBundles, options = {}) => {
4599
4824
  *
4600
4825
  * Also remove the reference from `deferredConnectedCallbacks` array
4601
4826
  * otherwise removed instances won't get garbage collected.
4827
+ *
4828
+ * Use `nextTick` (microtask) rather than `plt.raf` since
4829
+ * `requestAnimationFrame` callbacks do not fire while `document.hidden`
4602
4830
  */
4603
- plt.raf(() => {
4831
+ nextTick(() => {
4604
4832
  const hostRef = getHostRef(this);
4605
4833
  if (!hostRef) return;
4606
4834
  const i = deferredConnectedCallbacks.findIndex((host) => host === this);
@@ -4613,18 +4841,20 @@ const bootstrapLazy = (lazyBundles, options = {}) => {
4613
4841
  }
4614
4842
  };
4615
4843
  if (!(cmpMeta.$flags$ & CMP_FLAGS.shadowDomEncapsulation) && (BUILD.slotCloneNode || BUILD.patchClone && cmpMeta.$flags$ & CMP_FLAGS.patchClone)) patchCloneNode(HostElement.prototype);
4616
- if (!(cmpMeta.$flags$ & CMP_FLAGS.shadowDomEncapsulation) && cmpMeta.$flags$ & CMP_FLAGS.hasSlot) if (BUILD.lightDomPatches || BUILD.patchAll && cmpMeta.$flags$ & CMP_FLAGS.patchAll) applyLightDomPatches(HostElement.prototype);
4617
- else {
4618
- if (BUILD.slotChildNodes || BUILD.patchChildren && cmpMeta.$flags$ & CMP_FLAGS.patchChildren) patchChildSlotNodes(HostElement.prototype);
4619
- if (BUILD.slotDomMutations || BUILD.patchInsert && cmpMeta.$flags$ & CMP_FLAGS.patchInsert) {
4620
- patchSlotAppendChild(HostElement.prototype);
4621
- patchSlotAppend(HostElement.prototype);
4622
- patchSlotPrepend(HostElement.prototype);
4623
- patchSlotInsertAdjacentHTML(HostElement.prototype);
4624
- patchInsertBefore(HostElement.prototype);
4625
- patchSlotRemoveChild(HostElement.prototype);
4844
+ if (!(cmpMeta.$flags$ & CMP_FLAGS.shadowDomEncapsulation) && cmpMeta.$flags$ & CMP_FLAGS.hasSlot) {
4845
+ if (BUILD.lightDomPatches || BUILD.patchAll && cmpMeta.$flags$ & CMP_FLAGS.patchAll) applyLightDomPatches(HostElement.prototype);
4846
+ else {
4847
+ if (BUILD.slotChildNodes || BUILD.patchChildren && cmpMeta.$flags$ & CMP_FLAGS.patchChildren) patchChildSlotNodes(HostElement.prototype);
4848
+ if (BUILD.slotDomMutations || BUILD.patchInsert && cmpMeta.$flags$ & CMP_FLAGS.patchInsert) {
4849
+ patchSlotAppendChild(HostElement.prototype);
4850
+ patchSlotAppend(HostElement.prototype);
4851
+ patchSlotPrepend(HostElement.prototype);
4852
+ patchSlotInsertAdjacentHTML(HostElement.prototype);
4853
+ patchInsertBefore(HostElement.prototype);
4854
+ patchSlotRemoveChild(HostElement.prototype);
4855
+ }
4856
+ if (BUILD.slotTextContent) patchTextContent(HostElement.prototype);
4626
4857
  }
4627
- if (BUILD.slotTextContent) patchTextContent(HostElement.prototype);
4628
4858
  }
4629
4859
  if (BUILD.formAssociated && cmpMeta.$flags$ & CMP_FLAGS.formAssociated) HostElement.formAssociated = true;
4630
4860
  if (BUILD.hotModuleReplacement) HostElement.prototype["s-hmr"] = function(hmrVersionId) {
@@ -4670,9 +4900,10 @@ const addHostEventListeners = (elm, hostRef, listeners) => {
4670
4900
  };
4671
4901
  const hostListenerProxy = (hostRef, methodName) => (ev) => {
4672
4902
  try {
4673
- if (BUILD.lazyLoad) if (hostRef.$flags$ & HOST_FLAGS.isListenReady) hostRef.$lazyInstance$?.[methodName](ev);
4674
- else (hostRef.$queuedListeners$ = hostRef.$queuedListeners$ || []).push([methodName, ev]);
4675
- else hostRef.$hostElement$[methodName](ev);
4903
+ if (BUILD.lazyLoad) {
4904
+ if (hostRef.$flags$ & HOST_FLAGS.isListenReady) hostRef.$lazyInstance$?.[methodName](ev);
4905
+ else (hostRef.$queuedListeners$ = hostRef.$queuedListeners$ || []).push([methodName, ev]);
4906
+ } else hostRef.$hostElement$[methodName](ev);
4676
4907
  } catch (e) {
4677
4908
  consoleError(e, hostRef.$hostElement$);
4678
4909
  }
@@ -4706,6 +4937,73 @@ const setNonce = (nonce) => plt.$nonce$ = nonce;
4706
4937
  //#region src/runtime/platform-options.ts
4707
4938
  const setPlatformOptions = (opts) => Object.assign(plt, opts);
4708
4939
  //#endregion
4940
+ //#region src/runtime/reactive-controller.ts
4941
+ const ReactiveControllerHost = (Base) => class ReactiveControllerHostMixin extends Base {
4942
+ controllers = /* @__PURE__ */ new Set();
4943
+ #connected = false;
4944
+ #updateCompleteResolvers = [];
4945
+ addController(controller) {
4946
+ this.controllers.add(controller);
4947
+ if (this.#connected) controller.hostConnected?.();
4948
+ }
4949
+ removeController(controller) {
4950
+ this.controllers.delete(controller);
4951
+ }
4952
+ requestUpdate() {
4953
+ forceUpdate(this);
4954
+ }
4955
+ get updateComplete() {
4956
+ return new Promise((resolve) => this.#updateCompleteResolvers.push(resolve));
4957
+ }
4958
+ connectedCallback() {
4959
+ super.connectedCallback?.();
4960
+ this.#connected = true;
4961
+ const el = getElement(this);
4962
+ if (el && el !== this) {
4963
+ el.addController = (controller) => this.addController(controller);
4964
+ el.removeController = (controller) => this.removeController(controller);
4965
+ el.requestUpdate = () => this.requestUpdate();
4966
+ Object.defineProperty(el, "updateComplete", {
4967
+ configurable: true,
4968
+ get: () => this.updateComplete
4969
+ });
4970
+ }
4971
+ this.controllers.forEach((c) => c.hostConnected?.());
4972
+ }
4973
+ disconnectedCallback() {
4974
+ super.disconnectedCallback?.();
4975
+ this.#connected = false;
4976
+ this.controllers.forEach((c) => c.hostDisconnected?.());
4977
+ }
4978
+ async componentWillLoad() {
4979
+ await super.componentWillLoad?.();
4980
+ await Promise.all([...this.controllers].map((c) => c.hostWillLoad?.()));
4981
+ }
4982
+ componentDidLoad() {
4983
+ super.componentDidLoad?.();
4984
+ this.controllers.forEach((c) => c.hostDidLoad?.());
4985
+ }
4986
+ async componentWillRender() {
4987
+ await super.componentWillRender?.();
4988
+ await Promise.all([...this.controllers].map((c) => c.hostWillRender?.()));
4989
+ }
4990
+ componentDidRender() {
4991
+ super.componentDidRender?.();
4992
+ this.controllers.forEach((c) => c.hostDidRender?.());
4993
+ const resolvers = this.#updateCompleteResolvers;
4994
+ this.#updateCompleteResolvers = [];
4995
+ resolvers.forEach((resolve) => resolve(true));
4996
+ }
4997
+ async componentWillUpdate() {
4998
+ await super.componentWillUpdate?.();
4999
+ await Promise.all([...this.controllers].map((c) => c.hostWillUpdate?.()));
5000
+ }
5001
+ componentDidUpdate() {
5002
+ super.componentDidUpdate?.();
5003
+ this.controllers.forEach((c) => c.hostDidUpdate?.());
5004
+ }
5005
+ };
5006
+ //#endregion
4709
5007
  //#region src/runtime/render.ts
4710
5008
  /**
4711
5009
  * A WeakMap to persist HostRef objects across multiple render() calls to the
@@ -4792,4 +5090,4 @@ function hasKeys(obj) {
4792
5090
  return false;
4793
5091
  }
4794
5092
  //#endregion
4795
- export { Fragment, HYDRATED_STYLE_ID, Host, Mixin, addHostEventListeners, bootstrapLazy, connectedCallback, createEvent, defineCustomElement, disconnectedCallback, forceModeUpdate, forceUpdate, getAssetPath, getElement, getMode, getRegistry, getRenderingRef, getShadowRoot, getValue, h, jsx, jsxDEV, jsxs, normalizeWatchers, parsePropertyValue, postUpdateComponent, proxyComponent, proxyCustomElement, render, setAssetPath, setMode, setNonce, setPlatformOptions, setRegistry, setTagTransformer, setValue, transformTag };
5093
+ export { Fragment, HYDRATED_STYLE_ID, Host, Mixin, ReactiveControllerHost, addHostEventListeners, bootstrapLazy, connectedCallback, createEvent, defineCustomElement, disconnectedCallback, forceModeUpdate, forceUpdate, getAssetPath, getElement, getMode, getRegistry, getRenderingRef, getShadowRoot, getValue, h, jsx, jsxDEV, jsxs, normalizeWatchers, parsePropertyValue, postUpdateComponent, proxyComponent, proxyCustomElement, render, setAssetPath, setMode, setNonce, setPlatformOptions, setRegistry, setTagTransformer, setValue, transformTag };