@stencil/core 5.0.0-beta.34 → 5.0.0-beta.36

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.
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { C as Build, S as setErrorHandler, _ as getAssetPath, a as transformTag, b as writeTask, c as Mixin, d as Host, f as h, g as getShadowRoot, h as getElement, i as setTagTransformer, l as getMode, m as getRenderingRef, o as render, p as forceUpdate, s as ReactiveControllerHost, u as setMode, v as setAssetPath, x as setPlatformHelpers, y as readTask } from "./client-UbH-XkYu.mjs";
1
+ import { C as Build, S as setErrorHandler, _ as getAssetPath, a as transformTag, b as writeTask, c as Mixin, d as Host, f as h, g as getShadowRoot, h as getElement, i as setTagTransformer, l as getMode, m as getRenderingRef, o as render, p as forceUpdate, s as ReactiveControllerHost, u as setMode, v as setAssetPath, x as setPlatformHelpers, y as readTask } from "./client-CqQpuOUk.mjs";
2
2
  import { t as Fragment } from "./fragment-Di1hWOC8.mjs";
3
3
  //#region src/client/client-decorators.ts
4
4
  /**
@@ -1,3 +1,3 @@
1
- import { n as jsxDEV, r as jsxs, t as jsx } from "./client-UbH-XkYu.mjs";
1
+ import { n as jsxDEV, r as jsxs, t as jsx } from "./client-CqQpuOUk.mjs";
2
2
  import { t as Fragment } from "./fragment-Di1hWOC8.mjs";
3
3
  export { Fragment, jsx, jsxDEV, jsxs };
@@ -1,5 +1,5 @@
1
1
  import { n as __require } from "./rolldown-runtime-BhDjJH2R.mjs";
2
- import "./client-UbH-XkYu.mjs";
2
+ import "./client-CqQpuOUk.mjs";
3
3
  import { c as isFunction, f as isString, m as noop, r as flatOne } from "./helpers-Cpp3qc3u.mjs";
4
4
  import { X as TASK_CANCELED_MSG, Z as buildError, et as catchError, it as isGlob, q as normalizePath, rt as shouldIgnoreError } from "./util-C-H1H84W.mjs";
5
5
  import fs from "node:fs";
@@ -1137,7 +1137,9 @@ const patchTextContent = (hostElementPrototype) => {
1137
1137
  Object.defineProperty(hostElementPrototype, "textContent", {
1138
1138
  get: function() {
1139
1139
  let text = "";
1140
- (this.__childNodes ? this.childNodes : getSlottedChildNodes(this.childNodes)).forEach((node) => text += node.textContent || "");
1140
+ (this.__childNodes ? this.childNodes : getSlottedChildNodes(this.childNodes)).forEach((node) => {
1141
+ if (node.nodeType !== NODE_TYPE.CommentNode) text += node.textContent || "";
1142
+ });
1141
1143
  return text;
1142
1144
  },
1143
1145
  set: function(value) {
@@ -1145,7 +1147,7 @@ const patchTextContent = (hostElementPrototype) => {
1145
1147
  if (node["s-ol"]) node["s-ol"].remove();
1146
1148
  node.remove();
1147
1149
  });
1148
- this.insertAdjacentHTML("beforeend", value);
1150
+ if (value != null && value !== "") this.append(this.ownerDocument.createTextNode(String(value)));
1149
1151
  }
1150
1152
  });
1151
1153
  };
@@ -1786,7 +1788,7 @@ let _registry;
1786
1788
  const setRegistry = (registry) => {
1787
1789
  _registry = registry;
1788
1790
  };
1789
- const getRegistry = () => _registry ?? customElements;
1791
+ const getRegistry = () => _registry ?? globalThis.customElements;
1790
1792
  /**
1791
1793
  * @param elm a defined component host
1792
1794
  * @returns the registry the host's class was defined in, else the active registry
@@ -3761,6 +3763,11 @@ const addSlottedNodes = (slottedNodes, slotNodeId, slotName, slotNode, hostId) =
3761
3763
  * @returns the first corresponding node of the type
3762
3764
  */
3763
3765
  const findCorrespondingNode = (node, type) => {
3766
+ if (type === NODE_TYPE.TextNode) {
3767
+ const next = node.nextSibling;
3768
+ if (next?.nodeType === NODE_TYPE.TextNode) return next;
3769
+ return node.parentNode.insertBefore(node.ownerDocument.createTextNode(""), next);
3770
+ }
3764
3771
  let sibling = node;
3765
3772
  do
3766
3773
  sibling = sibling.nextSibling;
@@ -5434,4 +5441,4 @@ function hasKeys(obj) {
5434
5441
  return false;
5435
5442
  }
5436
5443
  //#endregion
5437
- export { AttachInternals, AttrDeserialize, BUILD, Build, Component, Element$1 as Element, Env, Event, Fragment, H, H as HTMLElement, HYDRATED_STYLE_ID, Host, Listen, Method, Mixin, NAMESPACE, Prop, PropSerialize, ReactiveControllerHost, STENCIL_DEV_MODE, State, Watch, addHostEventListeners, bootstrapLazy, cmpModules, connectedCallback, consoleDevError, consoleDevInfo, consoleDevWarn, consoleError, createEvent, defineCustomElement, disconnectedCallback, forceModeUpdate, forceUpdate, getAssetPath, getElement, getHostRef, getMode, getRegistry, getRenderingRef, getShadowRoot, getValue, h, injectSideEffectStyle, isMemberInElement, jsx, jsxDEV, jsxs, loadModule, modeResolver, needsScopedSSR, nextTick, normalizeWatchers, parsePropertyValue, plt, postUpdateComponent, promiseResolve, proxyComponent, proxyCustomElement, readTask, registerHost, registerInstance, registerSideEffectStyleTarget, render, resolveVar, setAssetPath, setErrorHandler, setLazyLoadBasePath, setMode, setNonce, setPlatformHelpers, setPlatformOptions, setRegistry, setScopedSSR, setTagTransformer, setValue, styles, supportsConstructableStylesheets, supportsListenerOptions, supportsMutableAdoptedStyleSheets, transformTag, unregisterSideEffectStyleTarget, win, writeTask };
5444
+ export { AttachInternals, AttrDeserialize, BUILD, Build, Component, Element$1 as Element, Env, Event, Fragment, H, H as HTMLElement, HYDRATED_STYLE_ID, Host, Listen, Method, Mixin, NAMESPACE, Prop, PropSerialize, ReactiveControllerHost, STENCIL_DEV_MODE, State, Watch, addHostEventListeners, applySerializers, bootstrapLazy, cmpModules, connectedCallback, consoleDevError, consoleDevInfo, consoleDevWarn, consoleError, createEvent, defineCustomElement, disconnectedCallback, forceModeUpdate, forceUpdate, getAssetPath, getElement, getHostRef, getMode, getRegistry, getRenderingRef, getShadowRoot, getValue, h, injectSideEffectStyle, isMemberInElement, jsx, jsxDEV, jsxs, loadModule, modeResolver, needsScopedSSR, nextTick, normalizeWatchers, parsePropertyValue, plt, postUpdateComponent, promiseResolve, proxyComponent, proxyCustomElement, readTask, registerHost, registerInstance, registerSideEffectStyleTarget, render, resolveVar, setAssetPath, setErrorHandler, setLazyLoadBasePath, setMode, setNonce, setPlatformHelpers, setPlatformOptions, setRegistry, setScopedSSR, setTagTransformer, setValue, styles, supportsConstructableStylesheets, supportsListenerOptions, supportsMutableAdoptedStyleSheets, transformTag, unregisterSideEffectStyleTarget, win, writeTask };
@@ -1413,6 +1413,16 @@ interface SsrDocumentOptions {
1413
1413
  * Sets `document.referrer`
1414
1414
  */
1415
1415
  referrer?: string;
1416
+ /**
1417
+ * Render into one long-lived mock window, reset between renders, instead of creating a new one
1418
+ * for every call. Skips evaluating the whole SSR platform (runtime and every component)
1419
+ * on each render: most of the cost of rendering a small fragment, and a good part of a whole page.
1420
+ *
1421
+ * Applies to HTML string input (not a `Document`). One window per distinct `serializeShadowRoot` value,
1422
+ * and renders sharing a window run one at a time.
1423
+ * Defaults to `false`, except in the `ssr-wasm` output target, where it defaults to `true`.
1424
+ */
1425
+ reuseWindow?: boolean;
1416
1426
  /**
1417
1427
  * Removes every `<script>` element found in the `document`. Defaults to `false`.
1418
1428
  */
@@ -1544,6 +1554,12 @@ interface SsrFactoryOptions extends SerializeDocumentOptions {
1544
1554
  serializeToHtml: boolean;
1545
1555
  destroyWindow: boolean;
1546
1556
  destroyDocument: boolean;
1557
+ /**
1558
+ * A canonical key for `serializeShadowRoot`, set by the renderer. Renders with the same key
1559
+ * render every component the same way, so they can share an SSR platform.
1560
+ * @internal
1561
+ */
1562
+ serializeShadowRootKey?: string;
1547
1563
  }
1548
1564
  //#endregion
1549
1565
  //#region src/declarations/stencil-private.d.ts
@@ -2511,6 +2527,7 @@ declare function render(vnode: VNode, container: Element): void;
2511
2527
  declare const HYDRATED_STYLE_ID = "sty-id";
2512
2528
  //#endregion
2513
2529
  //#region src/runtime/set-value.d.ts
2530
+ declare const applySerializers: (hostRef: HostRef, cmpMeta: ComponentRuntimeMeta, propName: string, val: any, instance: any) => void;
2514
2531
  declare const getValue: (ref: RuntimeRef, propName: string) => any;
2515
2532
  declare const setValue: (ref: RuntimeRef, propName: string, newVal: any, cmpMeta: ComponentRuntimeMeta) => void;
2516
2533
  //#endregion
@@ -2547,4 +2564,4 @@ declare const jsxs: typeof jsx;
2547
2564
  */
2548
2565
  declare const jsxDEV: typeof jsx;
2549
2566
  //#endregion
2550
- export { AttachInternals, AttrDeserialize, BUILD, Build, Component, Element$1 as Element, Env, Event, Fragment, H, H as HTMLElement, type HTMLStencilElement, HYDRATED_STYLE_ID, Host, type JSXBase, Listen, Method, Mixin, NAMESPACE, Prop, PropSerialize, ReactiveControllerHost, STENCIL_DEV_MODE, State, Watch, addHostEventListeners, bootstrapLazy, cmpModules, connectedCallback, consoleDevError, consoleDevInfo, consoleDevWarn, consoleError, createEvent, defineCustomElement, disconnectedCallback, forceModeUpdate, forceUpdate, getAssetPath, getElement, getHostRef, getMode, getRegistry, getRenderingRef, getShadowRoot, getValue, h, injectSideEffectStyle, isMemberInElement, jsx, jsxDEV, jsxs, loadModule, modeResolver, needsScopedSSR, nextTick, normalizeWatchers, parsePropertyValue, plt, postUpdateComponent, promiseResolve, proxyComponent, proxyCustomElement, readTask, registerHost, registerInstance, registerSideEffectStyleTarget, render, resolveVar, setAssetPath, setErrorHandler, setLazyLoadBasePath, setMode, setNonce, setPlatformHelpers, setPlatformOptions, setRegistry, setScopedSSR, setTagTransformer, setValue, styles, supportsConstructableStylesheets, supportsListenerOptions, supportsMutableAdoptedStyleSheets, transformTag, unregisterSideEffectStyleTarget, win, writeTask };
2567
+ export { AttachInternals, AttrDeserialize, BUILD, Build, Component, Element$1 as Element, Env, Event, Fragment, H, H as HTMLElement, type HTMLStencilElement, HYDRATED_STYLE_ID, Host, type JSXBase, Listen, Method, Mixin, NAMESPACE, Prop, PropSerialize, ReactiveControllerHost, STENCIL_DEV_MODE, State, Watch, addHostEventListeners, applySerializers, bootstrapLazy, cmpModules, connectedCallback, consoleDevError, consoleDevInfo, consoleDevWarn, consoleError, createEvent, defineCustomElement, disconnectedCallback, forceModeUpdate, forceUpdate, getAssetPath, getElement, getHostRef, getMode, getRegistry, getRenderingRef, getShadowRoot, getValue, h, injectSideEffectStyle, isMemberInElement, jsx, jsxDEV, jsxs, loadModule, modeResolver, needsScopedSSR, nextTick, normalizeWatchers, parsePropertyValue, plt, postUpdateComponent, promiseResolve, proxyComponent, proxyCustomElement, readTask, registerHost, registerInstance, registerSideEffectStyleTarget, render, resolveVar, setAssetPath, setErrorHandler, setLazyLoadBasePath, setMode, setNonce, setPlatformHelpers, setPlatformOptions, setRegistry, setScopedSSR, setTagTransformer, setValue, styles, supportsConstructableStylesheets, supportsListenerOptions, supportsMutableAdoptedStyleSheets, transformTag, unregisterSideEffectStyleTarget, win, writeTask };
@@ -1131,7 +1131,9 @@ const patchTextContent = (hostElementPrototype) => {
1131
1131
  Object.defineProperty(hostElementPrototype, "textContent", {
1132
1132
  get: function() {
1133
1133
  let text = "";
1134
- (this.__childNodes ? this.childNodes : getSlottedChildNodes(this.childNodes)).forEach((node) => text += node.textContent || "");
1134
+ (this.__childNodes ? this.childNodes : getSlottedChildNodes(this.childNodes)).forEach((node) => {
1135
+ if (node.nodeType !== NODE_TYPE.CommentNode) text += node.textContent || "";
1136
+ });
1135
1137
  return text;
1136
1138
  },
1137
1139
  set: function(value) {
@@ -1139,7 +1141,7 @@ const patchTextContent = (hostElementPrototype) => {
1139
1141
  if (node["s-ol"]) node["s-ol"].remove();
1140
1142
  node.remove();
1141
1143
  });
1142
- this.insertAdjacentHTML("beforeend", value);
1144
+ if (value != null && value !== "") this.append(this.ownerDocument.createTextNode(String(value)));
1143
1145
  }
1144
1146
  });
1145
1147
  };
@@ -1780,7 +1782,7 @@ let _registry;
1780
1782
  const setRegistry = (registry) => {
1781
1783
  _registry = registry;
1782
1784
  };
1783
- const getRegistry = () => _registry ?? customElements;
1785
+ const getRegistry = () => _registry ?? globalThis.customElements;
1784
1786
  /**
1785
1787
  * @param elm a defined component host
1786
1788
  * @returns the registry the host's class was defined in, else the active registry
@@ -3755,6 +3757,11 @@ const addSlottedNodes = (slottedNodes, slotNodeId, slotName, slotNode, hostId) =
3755
3757
  * @returns the first corresponding node of the type
3756
3758
  */
3757
3759
  const findCorrespondingNode = (node, type) => {
3760
+ if (type === NODE_TYPE.TextNode) {
3761
+ const next = node.nextSibling;
3762
+ if (next?.nodeType === NODE_TYPE.TextNode) return next;
3763
+ return node.parentNode.insertBefore(node.ownerDocument.createTextNode(""), next);
3764
+ }
3758
3765
  let sibling = node;
3759
3766
  do
3760
3767
  sibling = sibling.nextSibling;
@@ -5428,4 +5435,4 @@ function hasKeys(obj) {
5428
5435
  return false;
5429
5436
  }
5430
5437
  //#endregion
5431
- export { AttachInternals, AttrDeserialize, BUILD, Build, Component, Element$1 as Element, Env, Event, Fragment, H, H as HTMLElement, HYDRATED_STYLE_ID, Host, Listen, Method, Mixin, NAMESPACE, Prop, PropSerialize, ReactiveControllerHost, STENCIL_DEV_MODE, State, Watch, addHostEventListeners, bootstrapLazy, cmpModules, connectedCallback, consoleDevError, consoleDevInfo, consoleDevWarn, consoleError, createEvent, defineCustomElement, disconnectedCallback, forceModeUpdate, forceUpdate, getAssetPath, getElement, getHostRef, getMode, getRegistry, getRenderingRef, getShadowRoot, getValue, h, injectSideEffectStyle, isMemberInElement, jsx, jsxDEV, jsxs, loadModule, modeResolver, needsScopedSSR, nextTick, normalizeWatchers, parsePropertyValue, plt, postUpdateComponent, promiseResolve, proxyComponent, proxyCustomElement, readTask, registerHost, registerInstance, registerSideEffectStyleTarget, render, resolveVar, setAssetPath, setErrorHandler, setLazyLoadBasePath, setMode, setNonce, setPlatformHelpers, setPlatformOptions, setRegistry, setScopedSSR, setTagTransformer, setValue, styles, supportsConstructableStylesheets, supportsListenerOptions, supportsMutableAdoptedStyleSheets, transformTag, unregisterSideEffectStyleTarget, win, writeTask };
5438
+ export { AttachInternals, AttrDeserialize, BUILD, Build, Component, Element$1 as Element, Env, Event, Fragment, H, H as HTMLElement, HYDRATED_STYLE_ID, Host, Listen, Method, Mixin, NAMESPACE, Prop, PropSerialize, ReactiveControllerHost, STENCIL_DEV_MODE, State, Watch, addHostEventListeners, applySerializers, bootstrapLazy, cmpModules, connectedCallback, consoleDevError, consoleDevInfo, consoleDevWarn, consoleError, createEvent, defineCustomElement, disconnectedCallback, forceModeUpdate, forceUpdate, getAssetPath, getElement, getHostRef, getMode, getRegistry, getRenderingRef, getShadowRoot, getValue, h, injectSideEffectStyle, isMemberInElement, jsx, jsxDEV, jsxs, loadModule, modeResolver, needsScopedSSR, nextTick, normalizeWatchers, parsePropertyValue, plt, postUpdateComponent, promiseResolve, proxyComponent, proxyCustomElement, readTask, registerHost, registerInstance, registerSideEffectStyleTarget, render, resolveVar, setAssetPath, setErrorHandler, setLazyLoadBasePath, setMode, setNonce, setPlatformHelpers, setPlatformOptions, setRegistry, setScopedSSR, setTagTransformer, setValue, styles, supportsConstructableStylesheets, supportsListenerOptions, supportsMutableAdoptedStyleSheets, transformTag, unregisterSideEffectStyleTarget, win, writeTask };
@@ -199,6 +199,7 @@ declare function render(vnode: VNode, container: Element): void;
199
199
  declare const HYDRATED_STYLE_ID = "sty-id";
200
200
  //#endregion
201
201
  //#region src/runtime/set-value.d.ts
202
+ declare const applySerializers: (hostRef: HostRef, cmpMeta: ComponentRuntimeMeta, propName: string, val: any, instance: any) => void;
202
203
  declare const getValue: (ref: RuntimeRef, propName: string) => any;
203
204
  declare const setValue: (ref: RuntimeRef, propName: string, newVal: any, cmpMeta: ComponentRuntimeMeta) => void;
204
205
  //#endregion
@@ -235,4 +236,4 @@ declare const jsxs: typeof jsx;
235
236
  */
236
237
  declare const jsxDEV: typeof jsx;
237
238
  //#endregion
238
- export { Fragment, type HTMLStencilElement, HYDRATED_STYLE_ID, Host, type JSXBase, Mixin, ReactiveControllerHost, addHostEventListeners, bootstrapLazy, connectedCallback, createEvent, defineCustomElement, disconnectedCallback, forceModeUpdate, forceUpdate, getAssetPath, getElement, getMode, getRegistry, getRenderingRef, getShadowRoot, getValue, h, injectSideEffectStyle, jsx, jsxDEV, jsxs, normalizeWatchers, parsePropertyValue, postUpdateComponent, proxyComponent, proxyCustomElement, registerSideEffectStyleTarget, render, setAssetPath, setMode, setNonce, setPlatformOptions, setRegistry, setTagTransformer, setValue, transformTag, unregisterSideEffectStyleTarget };
239
+ export { Fragment, type HTMLStencilElement, HYDRATED_STYLE_ID, Host, type JSXBase, Mixin, ReactiveControllerHost, addHostEventListeners, applySerializers, bootstrapLazy, connectedCallback, createEvent, defineCustomElement, disconnectedCallback, forceModeUpdate, forceUpdate, getAssetPath, getElement, getMode, getRegistry, getRenderingRef, getShadowRoot, getValue, h, injectSideEffectStyle, jsx, jsxDEV, jsxs, normalizeWatchers, parsePropertyValue, postUpdateComponent, proxyComponent, proxyCustomElement, registerSideEffectStyleTarget, render, setAssetPath, setMode, setNonce, setPlatformOptions, setRegistry, setTagTransformer, setValue, transformTag, unregisterSideEffectStyleTarget };
@@ -1003,7 +1003,9 @@ const patchTextContent = (hostElementPrototype) => {
1003
1003
  Object.defineProperty(hostElementPrototype, "textContent", {
1004
1004
  get: function() {
1005
1005
  let text = "";
1006
- (this.__childNodes ? this.childNodes : getSlottedChildNodes(this.childNodes)).forEach((node) => text += node.textContent || "");
1006
+ (this.__childNodes ? this.childNodes : getSlottedChildNodes(this.childNodes)).forEach((node) => {
1007
+ if (node.nodeType !== NODE_TYPE.CommentNode) text += node.textContent || "";
1008
+ });
1007
1009
  return text;
1008
1010
  },
1009
1011
  set: function(value) {
@@ -1011,7 +1013,7 @@ const patchTextContent = (hostElementPrototype) => {
1011
1013
  if (node["s-ol"]) node["s-ol"].remove();
1012
1014
  node.remove();
1013
1015
  });
1014
- this.insertAdjacentHTML("beforeend", value);
1016
+ if (value != null && value !== "") this.append(this.ownerDocument.createTextNode(String(value)));
1015
1017
  }
1016
1018
  });
1017
1019
  };
@@ -1652,7 +1654,7 @@ let _registry;
1652
1654
  const setRegistry = (registry) => {
1653
1655
  _registry = registry;
1654
1656
  };
1655
- const getRegistry = () => _registry ?? customElements;
1657
+ const getRegistry = () => _registry ?? globalThis.customElements;
1656
1658
  /**
1657
1659
  * @param elm a defined component host
1658
1660
  * @returns the registry the host's class was defined in, else the active registry
@@ -3627,6 +3629,11 @@ const addSlottedNodes = (slottedNodes, slotNodeId, slotName, slotNode, hostId) =
3627
3629
  * @returns the first corresponding node of the type
3628
3630
  */
3629
3631
  const findCorrespondingNode = (node, type) => {
3632
+ if (type === NODE_TYPE.TextNode) {
3633
+ const next = node.nextSibling;
3634
+ if (next?.nodeType === NODE_TYPE.TextNode) return next;
3635
+ return node.parentNode.insertBefore(node.ownerDocument.createTextNode(""), next);
3636
+ }
3630
3637
  let sibling = node;
3631
3638
  do
3632
3639
  sibling = sibling.nextSibling;
@@ -5300,4 +5307,4 @@ function hasKeys(obj) {
5300
5307
  return false;
5301
5308
  }
5302
5309
  //#endregion
5303
- export { Fragment, HYDRATED_STYLE_ID, Host, Mixin, ReactiveControllerHost, addHostEventListeners, bootstrapLazy, connectedCallback, createEvent, defineCustomElement, disconnectedCallback, forceModeUpdate, forceUpdate, getAssetPath, getElement, getMode, getRegistry, getRenderingRef, getShadowRoot, getValue, h, injectSideEffectStyle, jsx, jsxDEV, jsxs, normalizeWatchers, parsePropertyValue, postUpdateComponent, proxyComponent, proxyCustomElement, registerSideEffectStyleTarget, render, setAssetPath, setMode, setNonce, setPlatformOptions, setRegistry, setTagTransformer, setValue, transformTag, unregisterSideEffectStyleTarget };
5310
+ export { Fragment, HYDRATED_STYLE_ID, Host, Mixin, ReactiveControllerHost, addHostEventListeners, applySerializers, bootstrapLazy, connectedCallback, createEvent, defineCustomElement, disconnectedCallback, forceModeUpdate, forceUpdate, getAssetPath, getElement, getMode, getRegistry, getRenderingRef, getShadowRoot, getValue, h, injectSideEffectStyle, jsx, jsxDEV, jsxs, normalizeWatchers, parsePropertyValue, postUpdateComponent, proxyComponent, proxyCustomElement, registerSideEffectStyleTarget, render, setAssetPath, setMode, setNonce, setPlatformOptions, setRegistry, setTagTransformer, setValue, transformTag, unregisterSideEffectStyleTarget };
@@ -218,6 +218,16 @@ interface SsrDocumentOptions {
218
218
  * Sets `document.referrer`
219
219
  */
220
220
  referrer?: string;
221
+ /**
222
+ * Render into one long-lived mock window, reset between renders, instead of creating a new one
223
+ * for every call. Skips evaluating the whole SSR platform (runtime and every component)
224
+ * on each render: most of the cost of rendering a small fragment, and a good part of a whole page.
225
+ *
226
+ * Applies to HTML string input (not a `Document`). One window per distinct `serializeShadowRoot` value,
227
+ * and renders sharing a window run one at a time.
228
+ * Defaults to `false`, except in the `ssr-wasm` output target, where it defaults to `true`.
229
+ */
230
+ reuseWindow?: boolean;
221
231
  /**
222
232
  * Removes every `<script>` element found in the `document`. Defaults to `false`.
223
233
  */
@@ -349,6 +359,12 @@ interface SsrFactoryOptions extends SerializeDocumentOptions {
349
359
  serializeToHtml: boolean;
350
360
  destroyWindow: boolean;
351
361
  destroyDocument: boolean;
362
+ /**
363
+ * A canonical key for `serializeShadowRoot`, set by the renderer. Renders with the same key
364
+ * render every component the same way, so they can share an SSR platform.
365
+ * @internal
366
+ */
367
+ serializeShadowRootKey?: string;
352
368
  }
353
369
  interface Diagnostic {
354
370
  absFilePath?: string | undefined;
@@ -50,6 +50,8 @@ const NODE_TYPE = {
50
50
  const HYDRATE_ID = "s-id";
51
51
  const HYDRATED_STYLE_ID = "sty-id";
52
52
  const HYDRATE_CHILD_ID = "c-id";
53
+ /** `Symbol.for()` key of the `ssrProp()` registry on the server's real global object. */
54
+ const SSR_PROPS_REGISTRY_KEY = "stencil.ssrProps";
53
55
  const HYDRATED_CSS = "{visibility:hidden}.hydrated{visibility:inherit}";
54
56
  const STENCIL_DOC_DATA = "_stencilDocData";
55
57
  const DEFAULT_DOC_DATA = {
@@ -799,7 +801,9 @@ const patchTextContent = (hostElementPrototype) => {
799
801
  Object.defineProperty(hostElementPrototype, "textContent", {
800
802
  get: function() {
801
803
  let text = "";
802
- (this.__childNodes ? this.childNodes : getSlottedChildNodes(this.childNodes)).forEach((node) => text += node.textContent || "");
804
+ (this.__childNodes ? this.childNodes : getSlottedChildNodes(this.childNodes)).forEach((node) => {
805
+ if (node.nodeType !== NODE_TYPE.CommentNode) text += node.textContent || "";
806
+ });
803
807
  return text;
804
808
  },
805
809
  set: function(value) {
@@ -807,7 +811,7 @@ const patchTextContent = (hostElementPrototype) => {
807
811
  if (node["s-ol"]) node["s-ol"].remove();
808
812
  node.remove();
809
813
  });
810
- this.insertAdjacentHTML("beforeend", value);
814
+ if (value != null && value !== "") this.append(this.ownerDocument.createTextNode(String(value)));
811
815
  }
812
816
  });
813
817
  };
@@ -1373,6 +1377,13 @@ const hydrateScopedToShadow = () => {
1373
1377
  */
1374
1378
  const isDef = (v) => v != null && v !== void 0;
1375
1379
  /**
1380
+ * Convert a string from PascalCase to dash-case
1381
+ *
1382
+ * @param str the string to convert
1383
+ * @returns a converted string
1384
+ */
1385
+ const toDashCase = (str) => str.replace(/([A-Z0-9])/g, (match) => ` ${match[0]}`).trim().split(" ").join("-").toLowerCase();
1386
+ /**
1376
1387
  * Check whether a value is a 'complex type', defined here as an object or a
1377
1388
  * function.
1378
1389
  *
@@ -1416,7 +1427,7 @@ const emitEvent = (elm, name, opts) => {
1416
1427
  elm.dispatchEvent(ev);
1417
1428
  return ev;
1418
1429
  };
1419
- const getRegistry = () => customElements;
1430
+ const getRegistry = () => globalThis.customElements;
1420
1431
  /**
1421
1432
  * @param elm a defined component host
1422
1433
  * @returns the registry the host's class was defined in, else the active registry
@@ -3389,6 +3400,11 @@ const addSlottedNodes = (slottedNodes, slotNodeId, slotName, slotNode, hostId) =
3389
3400
  * @returns the first corresponding node of the type
3390
3401
  */
3391
3402
  const findCorrespondingNode = (node, type) => {
3403
+ if (type === NODE_TYPE.TextNode) {
3404
+ const next = node.nextSibling;
3405
+ if (next?.nodeType === NODE_TYPE.TextNode) return next;
3406
+ return node.parentNode.insertBefore(node.ownerDocument.createTextNode(""), next);
3407
+ }
3392
3408
  let sibling = node;
3393
3409
  do
3394
3410
  sibling = sibling.nextSibling;
@@ -5029,7 +5045,10 @@ const insertVNodeAnnotations = (doc, hostElm, vnode, docData, cmpData) => {
5029
5045
  if (vnode != null) {
5030
5046
  const hostId = ++docData.hostIds;
5031
5047
  hostElm.setAttribute(HYDRATE_ID, hostId);
5032
- if (hostElm["s-cr"] != null) hostElm["s-cr"].nodeValue = `r.${hostId}`;
5048
+ if (hostElm["s-cr"] != null) {
5049
+ if (hostElm.shadowRoot) hostElm["s-cr"].remove();
5050
+ else hostElm["s-cr"].nodeValue = `r.${hostId}`;
5051
+ }
5033
5052
  if (vnode.$children$ != null) {
5034
5053
  const depth = 0;
5035
5054
  vnode.$children$.forEach((vnodeChild, index) => {
@@ -5091,7 +5110,14 @@ const insertChildVNodeAnnotations = (doc, vnodeChild, cmpData, hostId, depth, in
5091
5110
  };
5092
5111
  //#endregion
5093
5112
  //#region src/server/platform/proxy-host-element.ts
5094
- function proxyHostElement(elm, cstr) {
5113
+ /**
5114
+ * Set up a component's host element on the server: its props (from attributes, values set on
5115
+ * the element before it was defined, and `ssrProp()` references), getters/setters and shadow root.
5116
+ * @param elm the host element
5117
+ * @param cstr the component's constructor
5118
+ * @param warn report a problem with the render (to its `diagnostics`)
5119
+ */
5120
+ function proxyHostElement(elm, cstr, warn = () => {}) {
5095
5121
  const cmpMeta = cstr.cmpMeta;
5096
5122
  cmpMeta.$watchers$ = cmpMeta.$watchers$ || cstr.watchers;
5097
5123
  cmpMeta.$deserializers$ = cmpMeta.$deserializers$ || cstr.deserializers;
@@ -5108,7 +5134,9 @@ function proxyHostElement(elm, cstr) {
5108
5134
  Object.entries(cmpMeta.$members$).forEach(([memberName, [memberFlags, metaAttributeName]]) => {
5109
5135
  if (memberFlags & MEMBER_FLAGS.Prop) {
5110
5136
  const attributeName = metaAttributeName || memberName;
5111
- const attrValue = elm.getAttribute(attributeName);
5137
+ let attrValue = elm.getAttribute(attributeName);
5138
+ const ssrProp = takeSsrProp(elm, attributeName, memberName, warn);
5139
+ if (ssrProp) attrValue = null;
5112
5140
  const propValue = elm[memberName];
5113
5141
  let attrPropVal;
5114
5142
  const { get: origGetter, set: origSetter } = Object.getOwnPropertyDescriptor(cstr.prototype, memberName) || {};
@@ -5119,12 +5147,18 @@ function proxyHostElement(elm, cstr) {
5119
5147
  }
5120
5148
  else attrPropVal = parsePropertyValue(attrValue, memberFlags);
5121
5149
  }
5150
+ if (ssrProp?.value !== void 0) attrPropVal = ssrProp.value;
5122
5151
  if (propValue !== void 0) {
5123
5152
  attrPropVal = propValue;
5124
5153
  delete elm[memberName];
5125
5154
  }
5155
+ const setFromOutside = ssrProp?.value !== void 0 || propValue !== void 0;
5156
+ if (setFromOutside && typeof attrPropVal === "object" && attrPropVal !== null && !cmpMeta.$serializers$?.[memberName]) warn(`<${cmpMeta.$tagName$}>'s "${memberName}" prop was given an object on the server, but has no @PropSerialize(), so the browser won't get it: the component will first render there without it. To keep it, use @Prop({ serialize: 'json' }), or a @PropSerialize() / @AttrDeserialize() pair for other formats.`);
5126
5157
  const userSetter = !cstr.isProxied ? origSetter : void 0;
5127
- if (attrPropVal !== void 0 && !userSetter) hostRef?.$instanceValues$?.set(memberName, attrPropVal);
5158
+ if (attrPropVal !== void 0 && !userSetter) {
5159
+ hostRef?.$instanceValues$?.set(memberName, attrPropVal);
5160
+ if (setFromOutside && cmpMeta.$serializers$?.[memberName]) applySerializers(hostRef, cmpMeta, memberName, attrPropVal, void 0);
5161
+ }
5128
5162
  const getterSetterDescriptor = {
5129
5163
  get: function() {
5130
5164
  return getValue(this, memberName);
@@ -5172,6 +5206,34 @@ function componentOnReady() {
5172
5206
  return getHostRef(this)?.$onReadyPromise$;
5173
5207
  }
5174
5208
  function forceUpdate$1() {}
5209
+ /**
5210
+ * Read and remove an `ssrProp()` reference: a value a framework template passed to this prop,
5211
+ * which reached the server as an attribute pointing into the `ssrProp()` registry. Templates bind
5212
+ * it under the prop name, which HTML lower-cases (`chartData` -> `chartdata`), or dash-cased
5213
+ * (`chart-data`); complex props usually have no attribute name of their own.
5214
+ * @param elm the component's host element
5215
+ * @param attributeName the prop's attribute name
5216
+ * @param memberName the prop's name
5217
+ * @param warn report a problem with the render
5218
+ * @returns `undefined` if there's no reference, otherwise its value (`undefined` if it's gone)
5219
+ */
5220
+ const takeSsrProp = (elm, attributeName, memberName, warn) => {
5221
+ for (const name of /* @__PURE__ */ new Set([
5222
+ attributeName,
5223
+ memberName,
5224
+ toDashCase(memberName)
5225
+ ])) {
5226
+ const attr = elm.getAttribute(name);
5227
+ if (!attr?.startsWith("__stencil_ssr_ref:")) continue;
5228
+ elm.removeAttribute(name);
5229
+ const id = attr.slice(18);
5230
+ const registry = (typeof $stencilNativeGlobal !== "undefined" ? $stencilNativeGlobal : globalThis)[Symbol.for(SSR_PROPS_REGISTRY_KEY)];
5231
+ const entry = registry?.get(id);
5232
+ registry?.delete(id);
5233
+ if (!entry) warn(`<${elm.tagName.toLowerCase()}>'s "${memberName}" was passed with ssrProp(), but its value isn't available here: it's only available to renderToString() in the same process, for a short time after the template ran.`);
5234
+ return { value: entry?.value };
5235
+ }
5236
+ };
5175
5237
  //#endregion
5176
5238
  //#region src/server/platform/ssr-app.ts
5177
5239
  /**
@@ -5253,7 +5315,13 @@ function ssrApp(win, opts, results, afterSsr, resolve, abortController) {
5253
5315
  createdElements.add(elm);
5254
5316
  elm.connectedCallback = patchedConnectedCallback;
5255
5317
  registerHost(elm, Cstr.cmpMeta);
5256
- proxyHostElement(elm, Cstr);
5318
+ proxyHostElement(elm, Cstr, (messageText) => results.diagnostics.push({
5319
+ level: "warn",
5320
+ type: "hydrate",
5321
+ header: "SSR Warning",
5322
+ messageText,
5323
+ lines: []
5324
+ }));
5257
5325
  }
5258
5326
  }
5259
5327
  }
@@ -59,6 +59,16 @@ interface SsrDocumentOptions {
59
59
  * Sets `document.referrer`
60
60
  */
61
61
  referrer?: string;
62
+ /**
63
+ * Render into one long-lived mock window, reset between renders, instead of creating a new one
64
+ * for every call. Skips evaluating the whole SSR platform (runtime and every component)
65
+ * on each render: most of the cost of rendering a small fragment, and a good part of a whole page.
66
+ *
67
+ * Applies to HTML string input (not a `Document`). One window per distinct `serializeShadowRoot` value,
68
+ * and renders sharing a window run one at a time.
69
+ * Defaults to `false`, except in the `ssr-wasm` output target, where it defaults to `true`.
70
+ */
71
+ reuseWindow?: boolean;
62
72
  /**
63
73
  * Removes every `<script>` element found in the `document`. Defaults to `false`.
64
74
  */
@@ -190,6 +200,12 @@ interface SsrFactoryOptions extends SerializeDocumentOptions {
190
200
  serializeToHtml: boolean;
191
201
  destroyWindow: boolean;
192
202
  destroyDocument: boolean;
203
+ /**
204
+ * A canonical key for `serializeShadowRoot`, set by the renderer. Renders with the same key
205
+ * render every component the same way, so they can share an SSR platform.
206
+ * @internal
207
+ */
208
+ serializeShadowRootKey?: string;
193
209
  }
194
210
  interface Diagnostic {
195
211
  absFilePath?: string | undefined;
@@ -300,6 +316,14 @@ declare function ssrDocument(doc: any | string, options?: SsrDocumentOptions): P
300
316
  declare const hydrateDocument: typeof ssrDocument;
301
317
  declare function serializeDocumentToString(doc: Document, opts: SsrFactoryOptions): string;
302
318
  //#endregion
319
+ //#region src/server/runner/reusable-window.d.ts
320
+ /**
321
+ * Drop every reusable window and render queue. For hosts where a render can be abandoned without
322
+ * ever settling (the `ssr-wasm` plugin, when a call ends with a render still waiting), so the
323
+ * next render doesn't queue behind it forever.
324
+ */
325
+ declare function resetReusableWindows(): void;
326
+ //#endregion
303
327
  //#region src/server/runner/window-initialize.d.ts
304
328
  /**
305
329
  * Restart the hydration ids used by fragment renders (`fullDocument: false`).
@@ -324,4 +348,18 @@ declare function transformTag<T extends string>(tag: T): T;
324
348
  */
325
349
  declare function setTagTransformer(transformer: TagTransformer): void;
326
350
  //#endregion
327
- export { createWindowFromHtml, hydrateDocument, renderToString, resetSsrDocData, serializeDocumentToString, setTagTransformer, ssrDocument, streamToString, transformTag };
351
+ //#region src/server/runner/index.d.ts
352
+ /**
353
+ * Render components under transformed tag names, to match tag transformation on the client.
354
+ *
355
+ * Components are registered under their transformed names when a window's SSR platform is set up,
356
+ * so this also discards the reusable windows (see the `reuseWindow` option): later renders set up
357
+ * new ones that use the new transformer.
358
+ *
359
+ * (A function declaration with its own name, so the runtime's `setTagTransformer` keeps its name in
360
+ * the bundle - the SSR build looks for it - and this is hoisted.)
361
+ * @param transformer the tag transformer
362
+ */
363
+ declare function setTagTransformerForSsr(transformer: Parameters<typeof setTagTransformer>[0]): void;
364
+ //#endregion
365
+ export { createWindowFromHtml, hydrateDocument, renderToString, resetReusableWindows, resetSsrDocData, serializeDocumentToString, setTagTransformerForSsr as setTagTransformer, ssrDocument, streamToString, transformTag };